def _update_from_pokedex(self, species: str, store_species: bool = True) -> None: species = to_id_str(species) dex_entry = POKEDEX[species] if store_species: self._species = species self._base_stats = dex_entry["baseStats"] self._type_1 = PokemonType.from_name(dex_entry["types"][0]) if len(dex_entry["types"]) == 1: self._type_2 = None else: self._type_2 = PokemonType.from_name(dex_entry["types"][1]) self._possible_abilities = dex_entry["abilities"] self._heightm = dex_entry["heightm"] self._weightkg = dex_entry["weightkg"]
def __init__(self, move_id: str, raw_id: Optional[str] = None): self._id = move_id self._base_power_override = None if move_id.startswith("hiddenpower") and raw_id is not None: base_power = "".join([c for c in raw_id if c in STR_DIGITS]) self._id = "".join([c for c in to_id_str(raw_id) if c not in STR_DIGITS]) if base_power: try: base_power = int(base_power) self._base_power_override = base_power except ValueError: pass self._current_pp = self.max_pp self._is_empty: bool = False self._dynamaxed_move = None self._request_target = None
async def _parse_message(self, split_message: List[str]) -> None: if split_message[1] in self.MESSAGES_TO_IGNORE: return elif split_message[1] == "-ability": pokemon, ability = split_message[2:4] self.get_pokemon(pokemon).ability = ability elif split_message[1] == "-activate": target, effect = split_message[2:4] self.get_pokemon(target)._start_effect(effect) elif split_message[1] == "-boost": pokemon, stat, amount = split_message[2:5] self.get_pokemon(pokemon)._boost(stat, int(amount)) elif split_message[1] == "-burst": pokemon, species, item = split_message[2:5] self.get_pokemon(pokemon).burst(species, item) elif split_message[1] == "-clearallboost": self.active_pokemon._clear_boosts() self.opponent_active_pokemon._clear_boosts() elif split_message[1] == "-clearboost": pokemon = split_message[2] self.get_pokemon(pokemon)._clear_boosts() elif split_message[1] == "-clearnegativeboost": pokemon = split_message[2] self.get_pokemon(pokemon)._clear_negative_boosts() elif split_message[1] == "-clearpositiveboost": pokemon = split_message[2] self.get_pokemon(pokemon)._clear_positive_boosts() elif split_message[1] == "-copyboost": source, target = split_message[2:4] self.get_pokemon(target).copy_boosts(self.get_pokemon(source)) elif split_message[1] == "-curestatus": pokemon, status = split_message[2:4] self.get_pokemon(pokemon)._cure_status(status) elif split_message[1] == "-cureteam": self.logger.warning( "cureteam management not implemented in battle. Message: %s" % split_message ) elif split_message[1] == "-damage": pokemon, hp_status = split_message[2:4] self.get_pokemon(pokemon)._damage(hp_status) elif split_message[1] == "-end": pokemon, effect = split_message[2:4] self.get_pokemon(pokemon)._end_effect(effect) elif split_message[1] == "-endability": pokemon = split_message[2] self.get_pokemon(pokemon).ability = None elif split_message[1] == "-enditem": pokemon, item = split_message[2:4] self.get_pokemon(pokemon)._end_item(item) elif split_message[1] == "-fieldend": condition = split_message[2] self._field_end(condition) elif split_message[1] == "-fieldstart": condition = split_message[2] self._field_start(condition) elif split_message[1] in ["-formechange", "detailschange"]: pokemon, species = split_message[2:4] self.get_pokemon(pokemon)._forme_change(species) elif split_message[1] == "-heal": pokemon, hp_status = split_message[2:4] self.get_pokemon(pokemon)._heal(hp_status) elif split_message[1] == "-invertboost": pokemon = split_message[2] self.get_pokemon(pokemon).invertboosts() elif split_message[1] == "-item": pokemon, item = split_message[2:4] self.get_pokemon(pokemon).item = to_id_str(item) elif split_message[1] == "-mega": pokemon, megastone = split_message[2:4] self.get_pokemon(pokemon)._mega_evolve(megastone) elif split_message[1] == "-mustrecharge": pokemon = split_message[2] self.get_pokemon(pokemon).must_recharge = True elif split_message[1] == "-prepare": attacker, move, defender = split_message[2:5] self.get_pokemon(attacker)._prepare(move, self.get_pokemon(defender)) elif split_message[1] == "-primal": pokemon = split_message[2] self.get_pokemon(pokemon)._primal() elif split_message[1] == "-setboost": pokemon, stat, amount = split_message[2:5] self.get_pokemon(pokemon)._set_boost(stat, int(amount)) elif split_message[1] == "-sethp": pokemon, hp_status = split_message[2:4] self.get_pokemon(pokemon)._set_hp(hp_status) elif split_message[1] == "-sideend": side, condition = split_message[2:4] self._side_end(side, condition) elif split_message[1] == "-sidestart": side, condition = split_message[2:4] self._side_start(side, condition) elif split_message[1] == "-start": pokemon, effect = split_message[2:4] self.get_pokemon(pokemon)._start_effect(effect) elif split_message[1] == "-status": pokemon, status = split_message[2:4] self.get_pokemon(pokemon).status = status elif split_message[1] == "-swapboost": source, target, stats = split_message[2:5] self.get_pokemon(source).swap_boosts(self.get_pokemon(target)) elif split_message[1] == "-transform": pokemon, into = split_message[2:4] self.get_pokemon(pokemon)._transform(self.get_pokemon(into)) elif split_message[1] == "-unboost": pokemon, stat, amount = split_message[2:5] self.get_pokemon(pokemon)._boost(stat, -int(amount)) elif split_message[1] == "-weather": weather = split_message[2] self.weather = weather elif split_message[1] == "-zpower": pokemon = split_message[2] self.get_pokemon(pokemon)._used_z_move() elif split_message[1] == "clearpoke": self._in_team_preview = True elif split_message[1] in ["drag", "switch"]: pokemon, details, hp_status = split_message[2:5] self._switch(pokemon, hp_status) elif split_message[1] == "faint": pokemon = split_message[2] self.get_pokemon(pokemon)._faint() elif split_message[1] == "gen": self._format = split_message[2] elif split_message[1] == "move": pokemon, move, target = split_message[2:5] self.get_pokemon(pokemon)._moved(move) elif split_message[1] == "player": player, username, avatar, rating = split_message[2:6] if username == self._player_username: self._player_role = player return self._players.append( { "username": username, "player": player, "avatar": avatar, "rating": rating, } ) elif split_message[1] == "poke": player, details, item = split_message[2:5] self.register_pokemon(player, details, item) elif split_message[1] == "replace": pokemon = split_message[2] self._end_illusion(pokemon) elif split_message[1] == "rule": self._rules.append(split_message[2]) elif split_message[1] == "start": self._in_team_preview = False elif split_message[1] == "swap": pokemon, position = split_message[2:4] self._swap(pokemon, position) else: raise NotImplementedError(split_message)
def embed_battle(self, battle): final_state_dict = {} team = [] active_pokemon = battle.active_pokemon switches = battle.available_switches fainted_padding = [None] * (5 - len(switches)) pokemon_objects = [active_pokemon] + switches + fainted_padding assert len(pokemon_objects) == 6 for idx, pokemon in enumerate(pokemon_objects):#battle.team.keys(): #thought this was a method #pokemon = battle.team[pokemon_key] pokemon_information = {} #TODO: Bump the rest of these declarations to the top. species_id = 0 types = [0,0] move_ids = [0,0,0,0] move_pp = [0,0,0,0] move_type_ids = [0,0,0,0] move_powers = [0,0,0,0] move_accuracies = [0,0,0,0] move_physical_or_special = [0,0,0,0] item_id = 0 hp_percentage = [0] ability_id = 0 status_id = 0 scaled_stats = [0] * 6 boosts = [0] * 7 volatiles = [0] * len(relevant_conditions.volatiles) if not pokemon == None and not pokemon.fainted and not pokemon._species == "zoroark": # -1 indicates that the move does not have a base power # or is not available species_id = STR_TO_ID["species"][to_id_str(pokemon._species)] #Type ids types[0] = STR_TO_ID["types"][fix_type(pokemon.type_1.name)] if pokemon.type_2 is not None: types[1] = STR_TO_ID["types"][fix_type(pokemon.type_2.name)] else: pass #Move ids #move pp #move type #move power #move accuracy #physical or special or nondamaging for i, move in enumerate(pokemon.moves): if i == 4: break move_obj = pokemon.moves[move] #TODO: Sometimes this throws an error. Why? try: move_ids[i] = STR_TO_ID["moves"][move] except IndexError: print(pokemon) print(pokemon.moves) print(move_ids, move_obj) print("weirdo move error", move, i) print(STR_TO_ID["moves"][move]) try: move_pp[i] = move_obj._current_pp / move_obj.max_pp except ZeroDivisionError: print("Move division by zero for pp calc", move, move_obj._current_pp, pokemon._species) move_accuracies[i] = move_obj.accuracy move_type_ids[i] = STR_TO_ID["types"][fix_type(move_obj.type.name)] move_powers[i] = move_obj.base_power / 150.0 #TODO: Explosion? if move_obj.category.name == "PHYSICAL": move_physical_or_special[i] = 0 elif move_obj.category.name == "SPECIAL": move_physical_or_special[i] = 1 elif move_obj.category.name == "STATUS": move_physical_or_special[i] = 2 else: print("woops") sys.exit(1) #Item id if pokemon.item is not None: try: item_id = STR_TO_ID["items"][to_id_str(pokemon._item)] #noitem offset except KeyError: #TODO: Why does this happen? pass #Ability id ability_id = STR_TO_ID["abilities"][to_id_str(pokemon._ability)] #status if pokemon.status == Status.FNT: print("You shouldn't be in here") sys.exit(1) else: status_id = relevant_conditions.statuses.index(pokemon.status) #HP (%perentage) try: hp_percentage[0] = pokemon._current_hp * 1.0 / pokemon._max_hp except TypeError: print("calculating hp percentage failed for {}".format(pokemon._species)) for i, name in enumerate(["hp", "atk", "def", "spa", "spd", "spe"]): if name == "hp": stat = pokemon._max_hp stat_max = 669 stat_min = 15 #Min HP at level 50: 15 #Max HP at level 100: 669 else: stat = pokemon.stats[name] stat_max = 714 stat_min = 70 #Min other stat at level 100: 70 #Max other stat at level 100: 714 try: scaled_stats[i] = (stat - stat_min) / (1.0 * stat_max - stat_min) except TypeError: print("TypeError: Zoroark") scaled_stats[i] = 0 '''#TODO (longterm): NATURES #Base stats scaled_base_stats = [0] * 6 for i, (name, scaling_factor) in enumerate([ ("hp", 255), ("atk", 170), ("def", 230), ("spa", 170), ("spd", 230), ("spe", 160), ]): scaled_base_stats[i] = pokemon._base_stats[name] / (1.0 * scaling_factor) pokemon_information["base_stats"] = scaled_base_stats #IVs ivs = [0] * 6 print(pokemon.stats) for i, name in enumerate(["hp","atk", "def","spa","spd","spe"]): ivs[i] = pokemon.ivs[name] / 32.0 pokemon_information["ivs"] = ivs #EVs #Total EVs: 510 #Max per stat: 252 #Can only increment by 4 at a time #Number of increments = 252 / 4 evs = [0] * 6 for i, name in enumerate(["hp","atk", "def","spa","spd","spe"]): evs[i] = pokemon.evs[name] / 252.0 pokemon_information["evs"] = evs''' #boosts #For each stat "hp","atk", "def","spa","spd","spe" AND "eva", "acc" #Multipliers for stats #13 levels [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 ] #Acc: [-3, -2, -1, 0, 1, 2, 3] #TODO (longterm): What is the best encoding of these values? Scalar? 0 to 1? -1 to 1? #TODO: Change this for opponent too for i, name in enumerate(["atk", "def","spa","spd","spe", "evasion"]): boosts[i] = (pokemon.boosts[name] + 6) / 12.0 boosts[-1] = (pokemon.boosts["accuracy"] + 3) / 6.0 #volatiles active_effects = pokemon.effects volatiles = [1 if x in active_effects else 0 for x in relevant_conditions.volatiles] pokemon_information["species_id"] = species_id pokemon_information["type_ids"] = types pokemon_information["move_ids"] = move_ids pokemon_information["pp"] = move_pp pokemon_information["move_type_ids"] = move_type_ids pokemon_information["move_powers"] = move_powers pokemon_information["move_accuracies"] = move_accuracies pokemon_information["move_physical_or_special"] = move_physical_or_special pokemon_information["item_id"] = item_id pokemon_information["ability_id"] = ability_id pokemon_information["status_id"] = status_id pokemon_information["stats"] = scaled_stats pokemon_information["hp_percentage"] = hp_percentage pokemon_information["boosts"] = boosts pokemon_information["volatiles"] = volatiles team.append(pokemon_information) #isActive side_conditions = [0] * len(relevant_conditions.side_conditions) active_side_conditions = battle.side_conditions our_side_conditions = [1 if x in active_side_conditions else 0 for x in relevant_conditions.side_conditions ] final_state_dict["team"] = team final_state_dict["player_side_conditions"] = our_side_conditions opponent_team = [] opponent_pokemon_information = {} opponent_pokemon = battle.opponent_active_pokemon opponent_types = [0,0] opponent_species_id = 0 opponent_hp_percentage = [1] opponent_status_id = 0 opponent_scaled_base_stats = [0] * 6 opponent_boosts = [0] * 7 opponent_volatiles = [0] * len(relevant_conditions.volatiles) #opponent active pokemon id if battle.opponent_active_pokemon.fainted == False: opponent_species_id = STR_TO_ID["species"][to_id_str(opponent_pokemon._species)] #opponent pokemon type ids opponent_types[0] = STR_TO_ID["types"][fix_type(opponent_pokemon.type_1.name)] if opponent_pokemon.type_2 is not None: opponent_types[1] = STR_TO_ID["types"][fix_type(opponent_pokemon.type_2.name)] else: pass #Opponent HP (%expected perentage) #TODO: Does this code actually get the expected percentage based on the opponent's health bar? try: opponent_hp_percentage[0] = opponent_pokemon._current_hp * 1.0 / opponent_pokemon._max_hp except TypeError: print("calculating hp percentage failed for {}".format(opponent_pokemon._species)) #opponent status opponent_status_id = relevant_conditions.statuses.index(opponent_pokemon.status) #opponent base stats for i, (name, scaling_factor) in enumerate([ ("hp", 255), ("atk", 170), ("def", 230), ("spa", 170), ("spd", 230), ("spe", 160), ]): opponent_scaled_base_stats[i] = opponent_pokemon._base_stats[name] / (1.0 * scaling_factor) #opponent boost for i, name in enumerate(["atk", "def","spa","spd","spe", "evasion"]): opponent_boosts[i] = (opponent_pokemon.boosts[name] + 6) / 12.0 opponent_boosts[-1] = (opponent_pokemon.boosts["accuracy"] + 3) / 6.0 #opponent volatiles active_effects = opponent_pokemon.effects opponent_volatiles = [1 if x in active_effects else 0 for x in relevant_conditions.volatiles] #TODO (longterm): #Keeping track of opponent's moves #Keeping track of opponent's item #Keeping track of opponent's ability #Possible abilities opponent_pokemon_information["species_id"] = opponent_species_id opponent_pokemon_information["type_ids"] = opponent_types opponent_pokemon_information["hp_percentage"] = opponent_hp_percentage opponent_pokemon_information["boosts"] = opponent_boosts opponent_pokemon_information["base_stats"] = opponent_scaled_base_stats opponent_pokemon_information["volatiles"] = opponent_volatiles opponent_pokemon_information["status_id"] = opponent_status_id opponent_team.append(opponent_pokemon_information) opponent_side_conditions = [0] * len(relevant_conditions.side_conditions) opponent_active_side_conditions = battle.opponent_side_conditions opponent_side_conditions = [1 if x in opponent_active_side_conditions else 0 for x in relevant_conditions.side_conditions] final_state_dict["opponent_team"] = opponent_team final_state_dict["opponent_side_conditions"] = opponent_side_conditions weather = relevant_conditions.weathers.index(battle.weather) final_state_dict["weather"] = [weather] fields = [0] * len(relevant_conditions.fields) active_fields = battle.fields fields = [1 if x in active_fields else 0 for x in relevant_conditions.fields ] final_state_dict["fields"] = fields return final_state_dict
def _parse_message(self, split_message: List[str]) -> None: if split_message[1] in self.MESSAGES_TO_IGNORE: return elif split_message[1] == "-ability": pokemon, ability = split_message[2:4] self.get_pokemon(pokemon).ability = ability elif split_message[1] == "-activate": target, effect = split_message[2:4] if target: self.get_pokemon(target)._start_effect(effect) elif split_message[1] == "-boost": pokemon, stat, amount = split_message[2:5] self.get_pokemon(pokemon)._boost(stat, int(amount)) elif split_message[1] == "-clearallboost": self.active_pokemon._clear_boosts() if self.opponent_active_pokemon is not None: self.opponent_active_pokemon._clear_boosts() # pyre-ignore elif split_message[1] == "-clearboost": pokemon = split_message[2] self.get_pokemon(pokemon)._clear_boosts() elif split_message[1] == "-clearnegativeboost": pokemon = split_message[2] self.get_pokemon(pokemon)._clear_negative_boosts() elif split_message[1] == "-clearpositiveboost": pokemon = split_message[2] self.get_pokemon(pokemon)._clear_positive_boosts() elif split_message[1] == "-copyboost": source, target = split_message[2:4] self.get_pokemon(target)._copy_boosts(self.get_pokemon(source)) elif split_message[1] == "-curestatus": pokemon, status = split_message[2:4] self.get_pokemon(pokemon)._cure_status(status) elif split_message[1] == "-cureteam": self.logger.warning( "cureteam management not implemented in battle. Message: %s" % split_message ) elif split_message[1] == "-damage": pokemon, hp_status = split_message[2:4] self.get_pokemon(pokemon)._damage(hp_status) elif split_message[1] == "-end": pokemon, effect = split_message[2:4] self.get_pokemon(pokemon)._end_effect(effect) elif split_message[1] == "-endability": pokemon = split_message[2] self.get_pokemon(pokemon).ability = None elif split_message[1] == "-enditem": pokemon, item = split_message[2:4] self.get_pokemon(pokemon)._end_item(item) elif split_message[1] == "-fieldend": condition = split_message[2] self._field_end(condition) elif split_message[1] == "-fieldstart": condition = split_message[2] self._field_start(condition) elif split_message[1] in ["-formechange", "detailschange"]: pokemon, species = split_message[2:4] self.get_pokemon(pokemon)._forme_change(species) elif split_message[1] == "-heal": pokemon, hp_status = split_message[2:4] self.get_pokemon(pokemon)._heal(hp_status) elif split_message[1] == "-invertboost": pokemon = split_message[2] self.get_pokemon(pokemon)._invert_boosts() elif split_message[1] == "-item": pokemon, item = split_message[2:4] self.get_pokemon(pokemon).item = to_id_str(item) elif split_message[1] == "-mega": pokemon, megastone = split_message[2:4] self.get_pokemon(pokemon)._mega_evolve(megastone) elif split_message[1] == "-mustrecharge": pokemon = split_message[2] self.get_pokemon(pokemon).must_recharge = True elif split_message[1] == "-prepare": try: attacker, move, defender = split_message[2:5] self.get_pokemon(defender) except ValueError: attacker, move = split_message[2:4] defender = None self.get_pokemon(attacker)._prepare(move, defender) elif split_message[1] == "-primal": pokemon = split_message[2] self.get_pokemon(pokemon)._primal() elif split_message[1] == "-setboost": pokemon, stat, amount = split_message[2:5] self.get_pokemon(pokemon)._set_boost(stat, int(amount)) elif split_message[1] == "-sethp": pokemon, hp_status = split_message[2:4] self.get_pokemon(pokemon)._set_hp(hp_status) elif split_message[1] == "-sideend": side, condition = split_message[2:4] self._side_end(side, condition) elif split_message[1] == "-sidestart": side, condition = split_message[2:4] self._side_start(side, condition) elif split_message[1] == "-start": pokemon, effect = split_message[2:4] pokemon = self.get_pokemon(pokemon) pokemon._start_effect(effect) if pokemon.is_dynamaxed: if pokemon in set(self.team.values()) and self._dynamax_turn is None: self._dynamax_turn = self.turn # self._can_dynamax value is set via _parse_request() elif ( pokemon in set(self.opponent_team.values()) and self._opponent_dynamax_turn is None ): self._opponent_dynamax_turn = self.turn self._opponent_can_dynamax = False elif split_message[1] == "-status": pokemon, status = split_message[2:4] self.get_pokemon(pokemon).status = status elif split_message[1] == "-swapboost": source, target, stats = split_message[2:5] self.get_pokemon(target)._swap_boosts() elif split_message[1] == "-transform": pokemon, into = split_message[2:4] self.get_pokemon(pokemon)._transform(self.get_pokemon(into)) elif split_message[1] == "-unboost": pokemon, stat, amount = split_message[2:5] self.get_pokemon(pokemon)._boost(stat, -int(amount)) elif split_message[1] == "-weather": weather = split_message[2] self.weather = weather elif split_message[1] == "-zpower": pokemon = split_message[2] self.get_pokemon(pokemon)._used_z_move() elif split_message[1] == "clearpoke": self._in_team_preview = True elif split_message[1] in ["drag", "switch"]: pokemon, details, hp_status = split_message[2:5] self._switch(pokemon, details, hp_status) elif split_message[1] == "faint": pokemon = split_message[2] self.get_pokemon(pokemon)._faint() elif split_message[1] == "gen": self._format = split_message[2] elif split_message[1] == "move": pokemon, move, target = split_message[2:5] self.get_pokemon(pokemon)._moved(move) elif split_message[1] == "player": player, username, avatar, rating = split_message[2:6] if username == self._player_username: self._player_role = player return self._players.append( { "username": username, "player": player, "avatar": avatar, "rating": rating, } ) elif split_message[1] == "poke": player, details = split_message[2:4] self._register_teampreview_pokemon(player, details) elif split_message[1] == "raw": username, rating_info = split_message[2].split("'s rating: ") rating = int(rating_info[:4]) if username == self.player_username: self._rating = rating elif username == self.opponent_username: self._opponent_rating = rating else: self.logger.warning( "Rating information regarding an unrecognized username received. " "Received '%s', while only known players are '%s' and '%s'", username, self.player_username, self.opponent_username, ) elif split_message[1] == "replace": pokemon = split_message[2] details = split_message[3] self._end_illusion(pokemon, details) elif split_message[1] == "rule": self._rules.append(split_message[2]) elif split_message[1] == "start": self._in_team_preview = False elif split_message[1] == "swap": pokemon, position = split_message[2:4] self._swap(pokemon, position) elif split_message[1] == "teamsize": player, number = split_message[2:4] number = int(number) self._team_size[player] = number else: raise NotImplementedError(split_message)
def check_move_is_gyro_ball(self, move: Move) -> bool: return move.id == to_id_str("Gyro Ball")
def ability(self, ability: Optional[str]): if ability is None: self._ability = None else: self._ability = to_id_str(ability)
def _parse_message(self, split_message: List[str]) -> None: if self._save_replays: self._replay_data.append(split_message) if split_message[1] in self.MESSAGES_TO_IGNORE: return elif split_message[1] in ["drag", "switch"]: pokemon, details, hp_status = split_message[2:5] self._switch(pokemon, details, hp_status) elif split_message[1] == "-damage": pokemon, hp_status = split_message[2:4] self.get_pokemon(pokemon)._damage(hp_status) self._check_damage_message_for_item(split_message) self._check_damage_message_for_ability(split_message) elif split_message[1] == "move": failed = False override_move = None reveal_other_move = False for move_failed_suffix in ["[miss]", "[still]", "[notarget]"]: if split_message[-1] == move_failed_suffix: split_message = split_message[:-1] failed = True if split_message[-1] == "[notarget]": split_message = split_message[:-1] if split_message[-1] in { "[from]lockedmove", "[from]Pursuit", "[zeffect]" }: split_message = split_message[:-1] if split_message[-1].startswith("[anim]"): split_message = split_message[:-1] if split_message[-1] == "null": split_message = split_message[:-1] if split_message[-1].startswith("[from]move: "): override_move = split_message.pop()[12:] if override_move == "Sleep Talk": # Sleep talk was used, but also reveals another move reveal_other_move = True elif override_move == "Copycat": pass else: self.logger.warning( "Unmanaged [from]move message received - move %s in cleaned up " "message %s in battle %s turn %d", override_move, split_message, self.battle_tag, self.turn, ) if split_message[-1].startswith("[from]ability: "): revealed_ability = split_message.pop()[15:] pokemon = split_message[2] self.get_pokemon(pokemon).ability = revealed_ability if revealed_ability == "Magic Bounce": return elif revealed_ability == "Dancer": return else: self.logger.warning( "Unmanaged [from]ability: message received - ability %s in " "cleaned up message %s in battle %s turn %d", revealed_ability, split_message, self.battle_tag, self.turn, ) if split_message[-1] == "[from]Magic Coat": return if split_message[-1] == "": split_message = split_message[:-1] if len(split_message) == 4: pokemon, move = split_message[2:4] elif len(split_message) == 5: pokemon, move, presumed_target = split_message[2:5] if len(presumed_target) > 4 and presumed_target[:4] in { "p1: ", "p2: ", "p1a:", "p1b:", "p2a:", "p2b:", }: pass else: self.logger.warning( "Unmanaged move message format received - cleaned up message %s" " in battle %s turn %d", split_message, self.battle_tag, self.turn, ) else: pokemon, move, presumed_target = split_message[2:5] self.logger.warning( "Unmanaged move message format received - cleaned up message %s in " "battle %s turn %d", split_message, self.battle_tag, self.turn, ) if override_move: self.get_pokemon(pokemon)._moved(override_move, failed=failed) if override_move is None or reveal_other_move: self.get_pokemon(pokemon)._moved(move, failed=failed, use=not reveal_other_move) elif split_message[1] == "cant": pokemon, _ = split_message[2:4] self.get_pokemon(pokemon)._cant_move() elif split_message[1] == "turn": self.end_turn(int(split_message[2])) elif split_message[1] == "-heal": pokemon, hp_status = split_message[2:4] self.get_pokemon(pokemon)._heal(hp_status) self._check_heal_message_for_ability(split_message) self._check_heal_message_for_item(split_message) elif split_message[1] == "-boost": pokemon, stat, amount = split_message[2:5] self.get_pokemon(pokemon)._boost(stat, int(amount)) elif split_message[1] == "-weather": weather = split_message[2] if weather == "none": self._weather = {} return else: self._weather = { Weather.from_showdown_message(weather): self.turn } elif split_message[1] == "faint": pokemon = split_message[2] self.get_pokemon(pokemon)._faint() elif split_message[1] == "-unboost": pokemon, stat, amount = split_message[2:5] self.get_pokemon(pokemon)._boost(stat, -int(amount)) elif split_message[1] == "-ability": pokemon, ability = split_message[2:4] self.get_pokemon(pokemon).ability = ability elif split_message[1] == "-start": pokemon, effect = split_message[2:4] pokemon = self.get_pokemon(pokemon) pokemon._start_effect(effect) if pokemon.is_dynamaxed: if pokemon in set( self.team.values()) and self._dynamax_turn is None: self._dynamax_turn = self.turn # self._can_dynamax value is set via _parse_request() elif (pokemon in set(self.opponent_team.values()) and self._opponent_dynamax_turn is None): self._opponent_dynamax_turn = self.turn self.opponent_can_dynamax = False elif split_message[1] == "-activate": target, effect = split_message[2:4] if target: self.get_pokemon(target)._start_effect(effect) elif split_message[1] == "-status": pokemon, status = split_message[2:4] self.get_pokemon(pokemon).status = status elif split_message[1] == "rule": self._rules.append(split_message[2]) elif split_message[1] == "-clearallboost": self._clear_all_boosts() elif split_message[1] == "-clearboost": pokemon = split_message[2] self.get_pokemon(pokemon)._clear_boosts() elif split_message[1] == "-clearnegativeboost": pokemon = split_message[2] self.get_pokemon(pokemon)._clear_negative_boosts() elif split_message[1] == "-clearpositiveboost": pokemon = split_message[2] self.get_pokemon(pokemon)._clear_positive_boosts() elif split_message[1] == "-copyboost": source, target = split_message[2:4] self.get_pokemon(target)._copy_boosts(self.get_pokemon(source)) elif split_message[1] == "-curestatus": pokemon, status = split_message[2:4] self.get_pokemon(pokemon)._cure_status(status) elif split_message[1] == "-cureteam": pokemon = split_message[2] team = (self.team if pokemon[:2] == self._player_role else self._opponent_team) for mon in team.values(): mon._cure_status() elif split_message[1] == "-end": pokemon, effect = split_message[2:4] self.get_pokemon(pokemon)._end_effect(effect) elif split_message[1] == "-endability": pokemon = split_message[2] self.get_pokemon(pokemon).ability = None elif split_message[1] == "-enditem": pokemon, item = split_message[2:4] self.get_pokemon(pokemon)._end_item(item) elif split_message[1] == "-fieldend": condition = split_message[2] self._field_end(condition) elif split_message[1] == "-fieldstart": condition = split_message[2] self._field_start(condition) elif split_message[1] in ["-formechange", "detailschange"]: pokemon, species = split_message[2:4] self.get_pokemon(pokemon)._forme_change(species) elif split_message[1] == "-invertboost": pokemon = split_message[2] self.get_pokemon(pokemon)._invert_boosts() elif split_message[1] == "-item": pokemon, item = split_message[2:4] self.get_pokemon(pokemon).item = to_id_str(item) elif split_message[1] == "-mega": if not split_message[2].startswith( self._player_role): # pyre-ignore self._opponent_can_mega_evolve = False # pyre-ignore pokemon, megastone = split_message[2:4] self.get_pokemon(pokemon)._mega_evolve(megastone) elif split_message[1] == "-mustrecharge": pokemon = split_message[2] self.get_pokemon(pokemon).must_recharge = True elif split_message[1] == "-prepare": try: attacker, move, defender = split_message[2:5] defender = self.get_pokemon(defender) if to_id_str(move) == "skydrop": defender._start_effect("Sky Drop") except ValueError: attacker, move = split_message[2:4] defender = None self.get_pokemon(attacker)._prepare(move, defender) elif split_message[1] == "-primal": pokemon = split_message[2] self.get_pokemon(pokemon)._primal() elif split_message[1] == "-setboost": pokemon, stat, amount = split_message[2:5] self.get_pokemon(pokemon)._set_boost(stat, int(amount)) elif split_message[1] == "-sethp": pokemon, hp_status = split_message[2:4] self.get_pokemon(pokemon)._set_hp(hp_status) elif split_message[1] == "-sideend": side, condition = split_message[2:4] self._side_end(side, condition) elif split_message[1] == "-sidestart": side, condition = split_message[2:4] self._side_start(side, condition) elif split_message[1] == "-swapboost": source, target, stats = split_message[2:5] source = self.get_pokemon(source) target = self.get_pokemon(target) for stat in stats.split(", "): source._boosts[stat], target._boosts[stat] = ( target._boosts[stat], source._boosts[stat], ) elif split_message[1] == "-transform": pokemon, into = split_message[2:4] self.get_pokemon(pokemon)._transform(self.get_pokemon(into)) elif split_message[1] == "-zpower": if not split_message[2].startswith( self._player_role): # pyre-ignore self._opponent_can_mega_z_move = False # pyre-ignore pokemon = split_message[2] self.get_pokemon(pokemon)._used_z_move() elif split_message[1] == "clearpoke": self._in_team_preview = True elif split_message[1] == "gen": self._format = split_message[2] elif split_message[1] == "player": player, username, avatar, rating = split_message[2:6] if username == self._player_username: self._player_role = player return self._players.append({ "username": username, "player": player, "avatar": avatar, "rating": rating, }) elif split_message[1] == "poke": player, details = split_message[2:4] self._register_teampreview_pokemon(player, details) elif split_message[1] == "raw": username, rating_info = split_message[2].split("'s rating: ") rating = int(rating_info[:4]) if username == self.player_username: self._rating = rating elif username == self.opponent_username: self._opponent_rating = rating else: self.logger.warning( "Rating information regarding an unrecognized username received. " "Received '%s', while only known players are '%s' and '%s'", username, self.player_username, self.opponent_username, ) elif split_message[1] == "replace": pokemon = split_message[2] details = split_message[3] self._end_illusion(pokemon, details) elif split_message[1] == "start": self._in_team_preview = False elif split_message[1] == "swap": pokemon, position = split_message[2:4] self._swap(pokemon, position) elif split_message[1] == "teamsize": player, number = split_message[2:4] number = int(number) self._team_size[player] = number elif split_message[1] in {"message", "-message"}: self.logger.info("Received message: %s", split_message[2]) elif split_message[1] == "-immune": if len(split_message) == 4: mon, cause = split_message[2:] if cause.startswith("[from] ability:"): ability = cause.replace("[from] ability:", "") self.get_pokemon(mon).ability = to_id_str(ability) elif split_message[1] == "-swapsideconditions": self._side_conditions, self._opponent_side_conditions = ( self._opponent_side_conditions, self._side_conditions, ) elif split_message[1] == "title": player_1, player_2 = split_message[2].split(" vs. ") self.players = player_1, player_2 else: raise NotImplementedError(split_message)