def msg_select_unselect_card(self, data): data = io.BytesIO(data[1:]) player = self.read_u8(data) finishable = self.read_u8(data) cancelable = self.read_u8(data) min = self.read_u8(data) max = self.read_u8(data) select_size = self.read_u8(data) select_cards = [] for i in range(select_size): code = self.read_u32(data) loc = self.read_u32(data) card = Card(code) card.set_location(loc) select_cards.append(card) unselect_size = self.read_u8(data) unselect_cards = [] for i in range(unselect_size): code = self.read_u32(data) loc = self.read_u32(data) card = Card(code) card.set_location(loc) unselect_cards.append(card) self.cm.call_callbacks('select_unselect_card', player, finishable, cancelable, min, max, select_cards, unselect_cards) return data.read()
def msg_summoning(self, data, special=False): data = io.BytesIO(data[1:]) code = self.read_u32(data) card = Card(code) card.set_location(self.read_u32(data)) self.cm.call_callbacks('summoning', card, special=special) return data.read()
def msg_select_effectyn(self, data): data = io.BytesIO(data[1:]) player = self.read_u8(data) card = Card(self.read_u32(data)) card.set_location(self.read_u32(data)) desc = self.read_u32(data) self.cm.call_callbacks("select_effectyn", player, card, desc) return data.read()
def msg_set(self, data): data = io.BytesIO(data[1:]) code = self.read_u32(data) loc = self.read_u32(data) card = Card(code) card.set_location(loc) self.cm.call_callbacks('set', card) return data.read()
def msg_chaining(self, data): data = io.BytesIO(data[1:]) code = self.read_u32(data) card = Card(code) card.set_location(self.read_u32(data)) tc = self.read_u8(data) tl = self.read_u8(data) ts = self.read_u8(data) desc = self.read_u32(data) cs = self.read_u8(data) self.cm.call_callbacks('chaining', card, tc, tl, ts, desc, cs) return data.read()
def msg_swap(self, data): data = io.BytesIO(data[1:]) code1 = self.read_u32(data) location1 = self.read_u32(data) code2 = self.read_u32(data) location2 = self.read_u32(data) card1 = Card(code1) card1.set_location(location1) card2 = Card(code2) card2.set_location(location2) self.cm.call_callbacks('swap', card1, card2) return data.read()
def msg_select_chain(self, data): data = io.BytesIO(data[1:]) player = self.read_u8(data) size = self.read_u8(data) spe_count = self.read_u8(data) forced = self.read_u8(data) hint_timing = self.read_u32(data) other_timing = self.read_u32(data) chains = [] for i in range(size): et = self.read_u8(data) code = self.read_u32(data) loc = self.read_u32(data) card = Card(code) card.set_location(loc) desc = self.read_u32(data) chains.append((et, card, desc)) self.cm.call_callbacks('select_chain', player, size, spe_count, forced, chains) return data.read()
def move(self, code, location, newloc, reason): card = Card(code) card.set_location(location) cnew = Card(code) cnew.set_location(newloc) pl = self.players[card.controller] op = self.players[1 - card.controller] plspec = card.get_spec(pl) opspec = card.get_spec(op) plnewspec = cnew.get_spec(pl) opnewspec = cnew.get_spec(op) getspec = lambda p: plspec if p.duel_player == pl.duel_player else opspec getnewspec = lambda p: plnewspec if p.duel_player == pl.duel_player else opnewspec card_visible = True if card.position & POSITION.FACEDOWN and cnew.position & POSITION.FACEDOWN: card_visible = False getvisiblename = lambda p: card.get_name(p) if card_visible else p._( "Face-down card") if reason & REASON.DESTROY and card.location != cnew.location: self.inform( pl, (INFORM.ALLIES, lambda p: p._("Card %s (%s) destroyed.") % (plspec, card.get_name(p))), (INFORM.OPPONENTS, lambda p: p._("Card %s (%s) destroyed.") % (opspec, card.get_name(p)))) elif card.location == cnew.location and card.location & LOCATION.ONFIELD: if card.controller != cnew.controller: # controller changed too (e.g. change of heart) self.inform( pl, (INFORM.PLAYER, lambda p: p. _("your card {spec} ({name}) changed controller to {op} and is now located at {targetspec}." ).format(spec=plspec, name=card.get_name(p), op=op.nickname, targetspec=plnewspec)), (INFORM.OPPONENT, lambda p: p. _("you now control {plname}s card {spec} ({name}) and its located at {targetspec}." ).format(plname=pl.nickname, spec=opspec, name=card.get_name(p), targetspec=opnewspec)), (INFORM.WATCHERS | INFORM.TAG_PLAYERS, lambda p: p. _("{plname}s card {spec} ({name}) changed controller to {op} and is now located at {targetspec}." ).format(plname=pl.nickname, op=op.nickname, spec=getspec(p), targetspec=getnewspec(p), name=card.get_name(p))), ) else: # only column changed (alien decks e.g.) self.inform( pl, (INFORM.PLAYER, lambda p: p. _("your card {spec} ({name}) switched its zone to {targetspec}." ).format(spec=plspec, name=card.get_name(p), targetspec=plnewspec)), (INFORM.OTHER, lambda p: p. _("{plname}s card {spec} ({name}) changed its zone to {targetspec}." ).format(plname=pl.nickname, spec=getspec(p), targetspec=getnewspec(p), name=card.get_name(p))), ) elif reason & REASON.DISCARD and card.location != cnew.location: self.inform( pl, (INFORM.PLAYER, lambda p: p._("you discarded {spec} ({name})."). format(spec=plspec, name=card.get_name(p))), (INFORM.OTHER, lambda p: p._("{plname} discarded {spec} ({name}).").format( plname=pl.nickname, spec=getspec(p), name=card.get_name(p))), ) elif card.location == LOCATION.REMOVED and cnew.location & LOCATION.ONFIELD: self.inform( pl, (INFORM.PLAYER, lambda p: p. _("your banished card {spec} ({name}) returns to the field at {targetspec}." ).format( spec=plspec, name=card.get_name(p), targetspec=plnewspec)), (INFORM.OTHER, lambda p: p. _("{plname}'s banished card {spec} ({name}) returned to their field at {targetspec}." ).format(plname=pl.nickname, spec=getspec(p), targetspec=getnewspec(p), name=card.get_name(p))), ) elif card.location == LOCATION.GRAVE and cnew.location & LOCATION.ONFIELD: self.inform( pl, (INFORM.PLAYER, lambda p: p. _("your card {spec} ({name}) returns from the graveyard to the field at {targetspec}." ).format( spec=plspec, name=card.get_name(p), targetspec=plnewspec)), (INFORM.OTHER, lambda p: p. _("{plname}s card {spec} ({name}) returns from the graveyard to the field at {targetspec}." ).format(plname=pl.nickname, spec=getspec(p), targetspec=getnewspec(p), name=card.get_name(p))), ) elif cnew.location == LOCATION.HAND and card.location != cnew.location: self.inform( pl, (INFORM.PLAYER | INFORM.TAG_PLAYER, lambda p: p._("Card {spec} ({name}) returned to hand.").format( spec=plspec, name=card.get_name(p))), (INFORM.WATCHERS | INFORM.OPPONENTS, lambda p: p._( "{plname}'s card {spec} ({name}) returned to their hand."). format(plname=pl.nickname, spec=getspec(p), name=getvisiblename(p))), ) elif reason & (REASON.RELEASE | REASON.SUMMON) and card.location != cnew.location: self.inform( pl, (INFORM.PLAYER, lambda p: p._("You tribute {spec} ({name})."). format(spec=plspec, name=card.get_name(p))), (INFORM.OTHER, lambda p: p._("{plname} tributes {spec} ({name}).").format( plname=pl.nickname, spec=getspec(p), name=getvisiblename(p))), ) elif card.location == LOCATION.OVERLAY | LOCATION.MZONE and cnew.location & LOCATION.ONFIELD: self.inform( pl, (INFORM.PLAYER, lambda p: p._("you detached %s.") % (card.get_name(p))), (INFORM.OTHER, lambda p: p._("%s detached %s") % (pl.nickname, card.get_name(p))), ) elif card.location != cnew.location and cnew.location == LOCATION.GRAVE: self.inform( pl, (INFORM.PLAYER, lambda p: p._( "your card {spec} ({name}) was sent to the graveyard.").format( spec=plspec, name=card.get_name(p))), (INFORM.OTHER, lambda p: p._( "{plname}'s card {spec} ({name}) was sent to the graveyard."). format(plname=pl.nickname, spec=getspec(p), name=card.get_name(p)) ), ) elif card.location != cnew.location and cnew.location == LOCATION.REMOVED: self.inform( pl, (INFORM.PLAYER, lambda p: p._("your card {spec} ({name}) was banished.").format( spec=plspec, name=card.get_name(p))), (INFORM.OTHER, lambda p: p. _("{plname}'s card {spec} ({name}) was banished.").format( plname=pl.nickname, spec=getspec(p), name=getvisiblename(p))), ) elif card.location != cnew.location and cnew.location == LOCATION.DECK: self.inform( pl, (INFORM.PLAYER, lambda p: p._("your card {spec} ({name}) returned to your deck." ).format(spec=plspec, name=card.get_name(p))), (INFORM.OTHER, lambda p: p._( "{plname}'s card {spec} ({name}) returned to their deck."). format(plname=pl.nickname, spec=getspec(p), name=getvisiblename(p))), ) elif card.location != cnew.location and cnew.location == LOCATION.EXTRA: self.inform( pl, (INFORM.PLAYER, lambda p: p._( "your card {spec} ({name}) returned to your extra deck."). format(spec=plspec, name=card.get_name(pl))), (INFORM.OTHER, lambda p: p ._("{plname}'s card {spec} ({name}) returned to their extra deck." ).format( plname=pl.nickname, spec=getspec(p), name=card.get_name(p)) ), ) elif card.location == LOCATION.DECK and cnew.location == LOCATION.SZONE: def fn(p): if p.soundpack and cnew.type & TYPE.SPELL: p.notify("### activate_spell") elif p.soundpack and cnew.type & TYPE.TRAP: p.notify("### activate_trap") if p is pl: if cnew.position & POSITION.FACEDOWN: return p._("You set %s (%s) in %s position.") % ( cnew.get_spec(p), cnew.get_name(p), cnew.get_position(p)) else: return p._("Activating {0} ({1})").format( cnew.get_spec(p), cnew.get_name(p)) else: if cnew.position & POSITION.FACEDOWN: return p._("%s sets %s in %s position.") % ( pl.nickname, cnew.get_spec(p), cnew.get_position(p)) else: return p._("{0} activating {1} ({2})").format( pl.nickname, cnew.get_spec(p), cnew.get_name(p)) self.inform(pl, (INFORM.ALL, fn)) elif cnew.location == (LOCATION.OVERLAY | LOCATION.MZONE): attached_to = self.get_card(cnew.controller, cnew.location ^ LOCATION.OVERLAY, cnew.sequence) self.inform( pl, (INFORM.PLAYER, lambda p: p. _("your card {spec} ({name}) was attached to {targetspec} ({targetname}) as XYZ material" ).format(spec=getspec(p), name=card.get_name(p), targetspec=attached_to.get_spec(p), targetname=attached_to.get_name(p))), (INFORM.OTHER, lambda p: p. _("{plname}'s card {spec} ({name}) was attached to {targetspec} ({targetname}) as XYZ material" ).format(spec=getspec(p), name=card.get_name(p), targetspec=attached_to.get_spec(p), targetname=attached_to.get_name(p), plname=pl.nickname)), )
def move(self, code, location, newloc, reason): card = Card(code) card.set_location(location) pl = self.players[card.controller] op = self.players[1 - card.controller] plspec = card.get_spec(pl.duel_player) ploc = (location >> 8) & 0xff pnewloc = (newloc >> 8) & 0xff if reason & 0x01 and ploc != pnewloc: pl.notify(pl._("Card %s (%s) destroyed.") % (plspec, card.get_name(pl))) for w in self.watchers+[op]: s = card.get_spec(w.duel_player) w.notify(w._("Card %s (%s) destroyed.") % (s, card.get_name(w))) elif ploc == pnewloc and ploc in (LOCATION_MZONE, LOCATION_SZONE): cnew = Card(code) cnew.set_location(newloc) if (location & 0xff) != (newloc & 0xff): # controller changed too (e.g. change of heart) pl.notify(pl._("your card {spec} ({name}) changed controller to {op} and is now located at {targetspec}.").format(spec=plspec, name = card.get_name(pl), op = op.nickname, targetspec = cnew.get_spec(pl.duel_player))) op.notify(op._("you now control {plname}s card {spec} ({name}) and its located at {targetspec}.").format(plname=pl.nickname, spec=card.get_spec(op.duel_player), name = card.get_name(op), targetspec = cnew.get_spec(op.duel_player))) for w in self.watchers: s = card.get_spec(w.duel_player) ts = cnew.get_spec(w.duel_player) w.notify(w._("{plname}s card {spec} ({name}) changed controller to {op} and is now located at {targetspec}.").format(plname=pl.nickname, op=op.nickname, spec=s, targetspec=ts, name=card.get_name(w))) else: # only place changed (alien decks e.g.) pl.notify(pl._("your card {spec} ({name}) switched its zone to {targetspec}.").format(spec=plspec, name=card.get_name(pl), targetspec=cnew.get_spec(pl.duel_player))) for w in self.watchers+[op]: s = card.get_spec(w.duel_player) ts = cnew.get_spec(w.duel_player) w.notify(w._("{plname}s card {spec} ({name}) changed its zone to {targetspec}.").format(plname=pl.nickname, spec=s, targetspec=ts, name=card.get_name(w))) elif reason & 0x4000 and ploc != pnewloc: pl.notify(pl._("you discarded {spec} ({name}).").format(spec = plspec, name = card.get_name(pl))) for w in self.watchers+[op]: s = card.get_spec(w.duel_player) w.notify(w._("{plname} discarded {spec} ({name}).").format(plname=pl.nickname, spec=s, name=card.get_name(w))) elif ploc == LOCATION_REMOVED and pnewloc in (LOCATION_SZONE, LOCATION_MZONE): cnew = Card(code) cnew.set_location(newloc) pl.notify(pl._("your banished card {spec} ({name}) returns to the field at {targetspec}.").format(spec=plspec, name=card.get_name(pl), targetspec=cnew.get_spec(pl.duel_player))) for w in self.watchers+[op]: s=card.get_spec(w.duel_player) ts = cnew.get_spec(w.duel_player) w.notify(w._("{plname}'s banished card {spec} ({name}) returned to their field at {targetspec}.").format(plname=pl.nickname, spec=s, targetspec=ts, name=card.get_name(w))) elif ploc == LOCATION_GRAVE and pnewloc in (LOCATION_SZONE, LOCATION_MZONE): cnew = Card(code) cnew.set_location(newloc) pl.notify(pl._("your card {spec} ({name}) returns from the graveyard to the field at {targetspec}.").format(spec=plspec, name=card.get_name(pl), targetspec=cnew.get_spec(pl.duel_player))) for w in self.watchers+[op]: s = card.get_spec(w.duel_player) ts = cnew.get_spec(w.duel_player) w.notify(w._("{plname}s card {spec} ({name}) returns from the graveyard to the field at {targetspec}.").format(plname = pl.nickname, spec=s, targetspec=ts, name = card.get_name(w))) elif pnewloc == LOCATION_HAND and ploc != pnewloc: pl.notify(pl._("Card {spec} ({name}) returned to hand.") .format(spec=plspec, name=card.get_name(pl))) for w in self.watchers+[op]: if card.position in (POS_FACEDOWN_DEFENSE, POS_FACEDOWN): name = w._("Face-down card") else: name = card.get_name(w) s = card.get_spec(w.duel_player) w.notify(w._("{plname}'s card {spec} ({name}) returned to their hand.") .format(plname=pl.nickname, spec=s, name=name)) elif reason & 0x12 and ploc != pnewloc: pl.notify(pl._("You tribute {spec} ({name}).") .format(spec=plspec, name=card.get_name(pl))) for w in self.watchers+[op]: s = card.get_spec(w.duel_player) if card.position in (POS_FACEDOWN_DEFENSE, POS_FACEDOWN): name = w._("%s card") % card.get_position(w) else: name = card.get_name(w) w.notify(w._("{plname} tributes {spec} ({name}).") .format(plname=pl.nickname, spec=s, name=name)) elif ploc == LOCATION_OVERLAY+LOCATION_MZONE and pnewloc in (LOCATION_GRAVE, LOCATION_REMOVED): pl.notify(pl._("you detached %s.")%(card.get_name(pl))) for w in self.watchers+[op]: w.notify(w._("%s detached %s")%(pl.nickname, card.get_name(w))) elif ploc != pnewloc and pnewloc == LOCATION_GRAVE: pl.notify(pl._("your card {spec} ({name}) was sent to the graveyard.").format(spec=plspec, name=card.get_name(pl))) for w in self.watchers+[op]: s = card.get_spec(w.duel_player) w.notify(w._("{plname}'s card {spec} ({name}) was sent to the graveyard.").format(plname=pl.nickname, spec=s, name=card.get_name(w))) elif ploc != pnewloc and pnewloc == LOCATION_REMOVED: pl.notify(pl._("your card {spec} ({name}) was banished.").format(spec=plspec, name=card.get_name(pl))) for w in self.watchers+[op]: if card.position in (POS_FACEDOWN_DEFENSE, POS_FACEDOWN): name = w._("%s card")%(card.get_position(w)) else: name = card.get_name(w) s = card.get_spec(w.duel_player) w.notify(w._("{plname}'s card {spec} ({name}) was banished.").format(plname=pl.nickname, spec=s, name=name)) elif ploc != pnewloc and pnewloc == LOCATION_DECK: pl.notify(pl._("your card {spec} ({name}) returned to your deck.").format(spec=plspec, name=card.get_name(pl))) for w in self.watchers+[op]: s = card.get_spec(w.duel_player) w.notify(w._("{plname}'s card {spec} ({name}) returned to their deck.").format(plname=pl.nickname, spec=s, name=card.get_name(w))) elif ploc != pnewloc and pnewloc == LOCATION_EXTRA: pl.notify(pl._("your card {spec} ({name}) returned to your extra deck.").format(spec=plspec, name=card.get_name(pl))) for w in self.watchers+[op]: s = card.get_spec(w.duel_player) w.notify(w._("{plname}'s card {spec} ({name}) returned to their extra deck.").format(plname=pl.nickname, spec=s, name=card.get_name(w)))