def switch_or_drag(battle, split_msg): """The opponent's pokemon has changed If the new one hasn't been seen, create it""" if is_opponent(battle, split_msg): battle.opponent.side_conditions[constants.TOXIC_COUNT] = 0 if battle.opponent.active is not None: # reset the boost of the pokemon being replaced battle.opponent.active.boosts.clear() # reset the volatile statuses of the pokemon being replaced battle.opponent.active.volatile_statuses.clear() # check if the pokemon exists in the reserves # if it does not, then the newly-created pokemon is used (for formats without team preview) pkmn = Pokemon.from_switch_string(split_msg[3]) pkmn = find_pokemon_in_reserves(pkmn.name, battle.opponent.reserve) if pkmn is None: pkmn = Pokemon.from_switch_string(split_msg[3]) else: battle.opponent.reserve.remove(pkmn) # pkmn != active is a special edge-case for Zoroark if battle.opponent.active is not None and pkmn != battle.opponent.active: battle.opponent.reserve.append(battle.opponent.active) battle.opponent.active = pkmn if battle.opponent.active.name in constants.UNKOWN_POKEMON_FORMES: battle.opponent.active = Pokemon.from_switch_string(split_msg[3]) else: battle.user.side_conditions[constants.TOXIC_COUNT] = 0 battle.user.active.boosts.clear()
def test_removes_pokemon_from_reserve_if_it_is_in_there(self): zoroark = Pokemon('zoroark', 82) self.battle.opponent.active = Pokemon('meloetta', 100) self.battle.opponent.reserve = [zoroark] split_msg = ['', '-replace', 'p2a: Zoroark', 'Zoroark, L82, M'] form_change(self.battle, split_msg) self.assertNotIn(zoroark, self.battle.opponent.reserve)
def test_arceus_ghost_switching_in(self): already_seen_pokemon = Pokemon('arceus', 100) self.battle.opponent.reserve.append(already_seen_pokemon) split_msg = ['', 'switch', 'p2a: Arceus', 'Arceus-Ghost', '100/100'] switch_or_drag(self.battle, split_msg) expected_pokemon = Pokemon('arceus-ghost', 100) self.assertEqual(expected_pokemon, self.battle.opponent.active)
def setUp(self): self.battle = Battle(None) self.battle.user.name = 'p1' self.battle.opponent.name = 'p2' self.battle.user.active = Pokemon('pikachu', 100) self.opponent_active = Pokemon('caterpie', 100) self.battle.opponent.active = self.opponent_active self.battle.opponent.reserve = []
def setUp(self): self.battle = Battle(None) self.battle.user.name = 'p1' self.battle.opponent.name = 'p2' self.opponent_active = Pokemon('caterpie', 100) self.battle.opponent.active = self.opponent_active self.user_active = Pokemon('weedle', 100) self.battle.user.active = self.user_active
def test_silvally_steel_replaces_silvally(self): already_seen_pokemon = Pokemon('silvally', 100) self.battle.opponent.reserve.append(already_seen_pokemon) split_msg = [ '', 'switch', 'p2a: silvally', 'Silvally-Steel, L100, M', '100/100' ] switch_or_drag(self.battle, split_msg) expected_pokemon = Pokemon('silvallysteel', 100) self.assertEqual(expected_pokemon, self.battle.opponent.active)
def setUp(self): self.battle = Battle(None) self.battle.user.name = 'p1' self.battle.opponent.name = 'p2' self.user_active = Pokemon('caterpie', 100) self.opponent_active = Pokemon('caterpie', 100) # manually set hp to 200 for testing purposes self.opponent_active.max_hp = 200 self.opponent_active.hp = 200 self.battle.opponent.active = self.opponent_active self.battle.user.active = self.user_active
def test_switch_opponents_pokemon_successfully_creates_new_pokemon_for_active( self): new_pkmn = Pokemon('weedle', 100) split_msg = ['', 'switch', 'p2a: weedle', 'Weedle, L100, M', '100/100'] switch_or_drag(self.battle, split_msg) self.assertEqual(new_pkmn, self.battle.opponent.active)
def test_already_seen_pokemon_is_the_same_object_as_the_one_in_the_reserve( self): already_seen_pokemon = Pokemon('weedle', 100) self.battle.opponent.reserve.append(already_seen_pokemon) split_msg = ['', 'switch', 'p2a: weedle', 'Weedle, L100, M', '100/100'] switch_or_drag(self.battle, split_msg) self.assertIs(already_seen_pokemon, self.battle.opponent.active)
def test_switch_into_already_seen_pokemon_does_not_create_a_new_pokemon( self): already_seen_pokemon = Pokemon('weedle', 100) self.battle.opponent.reserve.append(already_seen_pokemon) split_msg = ['', 'switch', 'p2a: weedle', 'Weedle, L100, M', '100/100'] switch_or_drag(self.battle, split_msg) self.assertEqual(1, len(self.battle.opponent.reserve))
def test_changes_with_formechange_message(self): self.battle.opponent.active = Pokemon('meloetta', 100) split_msg = [ '', '-formechange', 'p2a: Meloetta', 'Meloetta - Pirouette', '[msg]' ] form_change(self.battle, split_msg) self.assertEqual('meloettapirouette', self.battle.opponent.active.name)
def start_random_battle(self, user_json, opponent_switch_string): self.user.from_json(user_json, first_turn=True) pkmn_information = opponent_switch_string.split('|')[3] pkmn = Pokemon.from_switch_string(pkmn_information) self.opponent.active = pkmn self.started = True self.rqid = user_json[constants.RQID]
def test_preserves_base_name_when_form_changes(self): self.battle.opponent.active = Pokemon('meloetta', 100) split_msg = [ '', '-formechange', 'p2a: Meloetta', 'Meloetta - Pirouette', '[msg]' ] form_change(self.battle, split_msg) self.assertEqual('meloetta', self.battle.opponent.active.base_name)
def test_multiple_forme_changes_does_not_ruin_base_name(self): self.battle.user.active = Pokemon('pikachu', 100) self.battle.opponent.active = Pokemon('pikachu', 100) self.battle.opponent.reserve = [] self.battle.opponent.reserve.append(Pokemon('wishiwashi', 100)) m1 = [ '', 'switch', 'p2a: Wishiwashi', 'Wishiwashi, L100, M', '100/100' ] m2 = [ '', '-formechange', 'p2a: Wishiwashi', 'Wishiwashi-School', '', '[from] ability: Schooling' ] m3 = ['', 'switch', 'p2a: Pikachu', 'Pikachu, L100, M', '100/100'] m4 = [ '', 'switch', 'p2a: Wishiwashi', 'Wishiwashi, L100, M', '100/100' ] m5 = [ '', '-formechange', 'p2a: Wishiwashi', 'Wishiwashi-School', '', '[from] ability: Schooling' ] m6 = ['', 'switch', 'p2a: Pikachu', 'Pikachu, L100, M', '100/100'] m7 = [ '', 'switch', 'p2a: Wishiwashi', 'Wishiwashi, L100, M', '100/100' ] m8 = [ '', '-formechange', 'p2a: Wishiwashi', 'Wishiwashi-School', '', '[from] ability: Schooling' ] switch_or_drag(self.battle, m1) form_change(self.battle, m2) switch_or_drag(self.battle, m3) switch_or_drag(self.battle, m4) form_change(self.battle, m5) switch_or_drag(self.battle, m6) switch_or_drag(self.battle, m7) form_change(self.battle, m8) pkmn = Pokemon("wishiwashischool", 100) self.assertNotIn(pkmn, self.battle.opponent.reserve)
def initialize_team_preview(self, user_json, opponent_pokemon): self.user.from_json(user_json, first_turn=True) self.user.reserve.insert(0, self.user.active) self.user.active = None for pkmn_string in opponent_pokemon: pokemon = Pokemon.from_switch_string(pkmn_string) nature, evs = get_spread(pokemon.name) pokemon.set_spread(nature, evs) self.opponent.reserve.append(pokemon) self.started = True self.rqid = user_json[constants.RQID]
def form_change(battle, split_msg): if is_opponent(battle, split_msg): base_name = battle.opponent.active.base_name hp_percent = float( battle.opponent.active.hp) / battle.opponent.active.max_hp new_pokemon = Pokemon.from_switch_string(split_msg[3]) if new_pokemon in battle.opponent.reserve: battle.opponent.reserve.remove(new_pokemon) battle.opponent.active = new_pokemon battle.opponent.active.hp = hp_percent * battle.opponent.active.max_hp if battle.opponent.active.name != "zoroark": battle.opponent.active.base_name = base_name
def from_json(self, user_json, first_turn=False): if first_turn: existing_conditions = (None, None, None) else: existing_conditions = (self.active.name, self.active.boosts, self.active.volatile_statuses) try: trapped = user_json[constants.ACTIVE][0].get( constants.TRAPPED, False) maybe_trapped = user_json[constants.ACTIVE][0].get( constants.MAYBE_TRAPPED, False) self.trapped = trapped or maybe_trapped except KeyError: self.trapped = False try: can_mega_evo = user_json[constants.ACTIVE][0][ constants.CAN_MEGA_EVO] except KeyError: can_mega_evo = False try: can_ultra_burst = user_json[constants.ACTIVE][0][ constants.CAN_ULTRA_BURST] except KeyError: can_ultra_burst = False try: can_z_move = [] for m in user_json[constants.ACTIVE][0][constants.CAN_Z_MOVE]: if m is not None: can_z_move.append(True) else: can_z_move.append(False) except KeyError: can_z_move = [False, False, False, False] self.name = user_json[constants.SIDE][constants.ID] self.reserve.clear() for index, pkmn_dict in enumerate( user_json[constants.SIDE][constants.POKEMON]): pkmn = Pokemon.from_switch_string(pkmn_dict[constants.DETAILS]) pkmn.ability = pkmn_dict[constants.REQUEST_DICT_ABILITY] pkmn.index = index + 1 pkmn.hp, pkmn.status = get_pokemon_info_from_condition( pkmn_dict[constants.CONDITION]) pkmn.item = pkmn_dict[constants.ITEM] if pkmn_dict[ constants.ITEM] else None if pkmn_dict[constants.ACTIVE]: self.active = pkmn if existing_conditions[0] == pkmn.name: pkmn.boosts = existing_conditions[1] pkmn.volatile_statuses = existing_conditions[2] else: self.reserve.append(pkmn) for move_name in pkmn_dict[constants.MOVES]: if move_name.startswith(constants.HIDDEN_POWER): pkmn.add_move('{}{}'.format( move_name, constants. HIDDEN_POWER_RESERVE_MOVE_BASE_DAMAGE_STRING)) else: pkmn.add_move(move_name) # if there is no active pokemon, we do not want to look through it's moves if constants.ACTIVE not in user_json: return self.active.can_mega_evo = can_mega_evo self.active.can_ultra_burst = can_ultra_burst # clear the active moves so they can be reset by the options available self.active.moves.clear() # update the active pokemon's moves to show disabled status/pp remaining # this assumes that there is only one active pokemon (single-battle) for index, move in enumerate( user_json[constants.ACTIVE][0][constants.MOVES]): if move[constants.ID] == constants.HIDDEN_POWER: self.active.add_move('{}{}{}'.format( constants.HIDDEN_POWER, move['move'].split()[ constants.HIDDEN_POWER_TYPE_STRING_INDEX].lower(), constants.HIDDEN_POWER_ACTIVE_MOVE_BASE_DAMAGE_STRING)) else: self.active.add_move(move[constants.ID]) self.active.moves[-1].disabled = move.get(constants.DISABLED, False) self.active.moves[-1].current_pp = move.get(constants.PP, 1) if can_z_move[index]: self.active.moves[index].can_z = True
def test_does_not_set_base_name_for_illusion_ending(self): self.battle.opponent.active = Pokemon('meloetta', 100) split_msg = ['', 'replace', 'p2a: Zoroark', 'Zoroark, L84, F'] form_change(self.battle, split_msg) self.assertEqual('zoroark', self.battle.opponent.active.base_name)
def test_initialize_with_z_move_available(self): request_dict = { "active": [{ "moves": [{ "move": "Swords Dance", "id": "swordsdance", "pp": 32, "maxpp": 32, "target": "self", "disabled": False }, { "move": "Photon Geyser", "id": "photongeyser", "pp": 8, "maxpp": 8, "target": "normal", "disabled": False }, { "move": "Earthquake", "id": "earthquake", "pp": 16, "maxpp": 16, "target": "allAdjacent", "disabled": False }, { "move": "Stone Edge", "id": "stoneedge", "pp": 8, "maxpp": 8, "target": "normal", "disabled": False }], "canZMove": [ None, { "move": "Light That Burns the Sky", "target": "normal" }, None, None ] }], "side": { "name": "BigBluePikachu", "id": "p2", "pokemon": [{ "ident": "p2: Necrozma", "details": "Necrozma-Ultra", "condition": "152/335", "active": True, "stats": { "atk": 433, "def": 238, "spa": 333, "spd": 230, "spe": 385 }, "moves": ["swordsdance", "photongeyser", "earthquake", "stoneedge"], "baseAbility": "neuroforce", "item": "ultranecroziumz", "pokeball": "pokeball", "ability": "neuroforce" }, { "ident": "p2: Groudon", "details": "Groudon", "condition": "386/386", "active": False, "stats": { "atk": 336, "def": 284, "spa": 328, "spd": 216, "spe": 235 }, "moves": ["overheat", "stealthrock", "precipiceblades", "toxic"], "baseAbility": "drought", "item": "redorb", "pokeball": "pokeball", "ability": "drought" }, { "ident": "p2: Xerneas", "details": "Xerneas", "condition": "393/393", "active": False, "stats": { "atk": 268, "def": 226, "spa": 397, "spd": 233, "spe": 297 }, "moves": ["moonblast", "focusblast", "aromatherapy", "thunder"], "baseAbility": "fairyaura", "item": "choicescarf", "pokeball": "pokeball", "ability": "fairyaura" }, { "ident": "p2: Darkrai", "details": "Darkrai", "condition": "281/281", "active": False, "stats": { "atk": 194, "def": 217, "spa": 369, "spd": 216, "spe": 383 }, "moves": ["nastyplot", "darkpulse", "hypnosis", "thunder"], "baseAbility": "baddreams", "item": "lifeorb", "pokeball": "pokeball", "ability": "baddreams" }, { "ident": "p2: Arceus", "details": "Arceus-Dragon", "condition": "444/444", "active": False, "stats": { "atk": 248, "def": 292, "spa": 276, "spd": 276, "spe": 356 }, "moves": ["judgment", "fireblast", "defog", "recover"], "baseAbility": "multitype", "item": "dracoplate", "pokeball": "pokeball", "ability": "multitype" }, { "ident": "p2: Celesteela", "details": "Celesteela", "condition": "397/397", "active": False, "stats": { "atk": 238, "def": 335, "spa": 225, "spd": 240, "spe": 158 }, "moves": ["leechseed", "heavyslam", "toxic", "flamethrower"], "baseAbility": "beastboost", "item": "leftovers", "pokeball": "pokeball", "ability": "beastboost" }] }, "rqid": 7 } self.battler.active = Pokemon('pikachu', 100) self.battler.from_json(request_dict) # photongeyser is a z-move with the request dict given above photon_geyser = self.battler.active.get_move('photongeyser') self.assertTrue(photon_geyser.can_z)
def setUp(self): self.battle = Battle(None) self.battle.user.active = Pokemon("pikachu", 100) self.request_json = { "active": [{ "moves": [{ "move": "Storm Throw", "id": "stormthrow", "pp": 16, "maxpp": 16, "target": "normal", "disabled": False }, { "move": "Ice Punch", "id": "icepunch", "pp": 24, "maxpp": 24, "target": "normal", "disabled": False }, { "move": "Bulk Up", "id": "bulkup", "pp": 32, "maxpp": 32, "target": "self", "disabled": False }, { "move": "Knock Off", "id": "knockoff", "pp": 32, "maxpp": 32, "target": "normal", "disabled": False }] }], "side": { "name": "NiceNameNerd", "id": "p1", "pokemon": [{ "ident": "p1: Throh", "details": "Throh, L83, M", "condition": "335/335", "active": True, "stats": { "atk": 214, "def": 189, "spa": 97, "spd": 189, "spe": 122 }, "moves": ["stormthrow", "icepunch", "bulkup", "knockoff"], "baseAbility": "moldbreaker", "item": "leftovers", "pokeball": "pokeball", "ability": "moldbreaker" }, { "ident": "p1: Empoleon", "details": "Empoleon, L77, F", "condition": "256/256", "active": False, "stats": { "atk": 137, "def": 180, "spa": 215, "spd": 200, "spe": 137 }, "moves": ["icebeam", "grassknot", "scald", "flashcannon"], "baseAbility": "torrent", "item": "choicespecs", "pokeball": "pokeball", "ability": "torrent" }, { "ident": "p1: Emboar", "details": "Emboar, L79, M", "condition": "303/303", "active": False, "stats": { "atk": 240, "def": 148, "spa": 204, "spd": 148, "spe": 148 }, "moves": ["headsmash", "superpower", "flareblitz", "grassknot"], "baseAbility": "reckless", "item": "assaultvest", "pokeball": "pokeball", "ability": "reckless" }, { "ident": "p1: Zoroark", "details": "Zoroark, L77, M", "condition": "219/219", "active": False, "stats": { "atk": 166, "def": 137, "spa": 229, "spd": 137, "spe": 206 }, "moves": ["sludgebomb", "darkpulse", "flamethrower", "focusblast"], "baseAbility": "illusion", "item": "choicespecs", "pokeball": "pokeball", "ability": "illusion" }, { "ident": "p1: Reuniclus", "details": "Reuniclus, L78, M", "condition": "300/300", "active": False, "stats": { "atk": 106, "def": 162, "spa": 240, "spd": 178, "spe": 92 }, "moves": ["calmmind", "shadowball", "psyshock", "recover"], "baseAbility": "magicguard", "item": "lifeorb", "pokeball": "pokeball", "ability": "magicguard" }, { "ident": "p1: Moltres", "details": "Moltres, L77", "condition": "265/265", "active": False, "stats": { "atk": 159, "def": 183, "spa": 237, "spd": 175, "spe": 183 }, "moves": ["fireblast", "toxic", "hurricane", "roost"], "baseAbility": "flamebody", "item": "leftovers", "pokeball": "pokeball", "ability": "flamebody" }] }, "rqid": 2 }