diff --git a/src/poke_env/battle/pokemon.py b/src/poke_env/battle/pokemon.py index a0ac5b3ca..3c3da9265 100644 --- a/src/poke_env/battle/pokemon.py +++ b/src/poke_env/battle/pokemon.py @@ -47,6 +47,8 @@ class Pokemon: "_status", "_status_counter", "_temporary_ability", + "_temporary_base_stats", + "_temporary_moves", "_temporary_types", "_terastallized", "_terastallized_type", @@ -123,6 +125,8 @@ def __init__( self._status_counter: int = 0 self._temporary_ability: Optional[str] = None self._forme_change_ability: Optional[str] = None + self._temporary_base_stats: Optional[Dict[str, int]] = None + self._temporary_moves: Optional[Dict[str, Move]] = None self._temporary_types: List[PokemonType] = [] if request_pokemon: @@ -158,13 +162,15 @@ def _add_move(self, move_id: str, use: bool = False) -> Optional[Move]: if not Move.should_be_stored(id_, self._data.gen): return None - if id_ not in self._moves: + if id_ not in self.moves: move = Move(move_id=id_, raw_id=move_id, gen=self._data.gen) - self._moves[id_] = move + if len(self.moves) == 4: + self.moves = dict(list(self.moves.items())[1:]) + self.moves[id_] = move if use: - self._moves[id_].use() + self.moves[id_].use() - return self._moves[id_] + return self.moves[id_] def boost(self, stat: str, amount: int): self._boosts[stat] += amount @@ -270,6 +276,7 @@ def faint(self): self._current_hp = 0 self._status = Status.FNT self.temporary_ability = None + self._temporary_moves = None self._clear_effects() def forme_change(self, species: str): @@ -312,23 +319,6 @@ def moved(self, move_id: str, failed: bool = False, use: bool = True): if self._status == Status.SLP: self._status_counter += 1 - if len(self._moves) > 4: - new_moves = {} - - # Keep the current move - if move and move in self._moves.values(): - new_moves = { - move_id: m for move_id, m in self._moves.items() if m is move - } - - for move_name in self._moves: - if len(new_moves) == 4: - break - elif move_name not in new_moves: - new_moves[move_name] = self._moves[move_name] - - self._moves = new_moves - # Handle silent effect ending if Effect.GLAIVE_RUSH in self.effects: self.end_effect("Glaive Rush") @@ -455,6 +445,8 @@ def switch_out(self, fields: Dict[Field, int]): self._preparing_target = None self._protect_counter = 0 self.temporary_ability = None + self._temporary_base_stats = None + self._temporary_moves = None self._temporary_types = [] if self._status == Status.TOX: @@ -466,9 +458,16 @@ def terastallize(self, type_: str): self._temporary_types = [] def transform(self, into: Pokemon): - current_hp = self.current_hp - self._update_from_pokedex(into.species, store_species=False) - self._current_hp = int(current_hp) + dex_entry = self._data.pokedex[into.species] + self._heightm = dex_entry["heightm"] + self._weightkg = dex_entry["weightkg"] + self._temporary_base_stats = dex_entry["baseStats"] + if into.ability is not None: + self.ability = into.ability + self._temporary_types = [PokemonType.from_name(t) for t in dex_entry["types"]] + self._temporary_moves = {m.id: Move(m.id, m._gen) for m in into.moves.values()} + for m in self._temporary_moves.values(): + m._current_pp = 5 self._boosts = into.boosts.copy() def _update_from_pokedex(self, species: str, store_species: bool = True): @@ -577,16 +576,6 @@ def update_from_request(self, request_pokemon: Dict[str, Any]): for move in request_pokemon["moves"]: self._add_move(move) - if len(self._moves) > 4: - moves_to_keep = { - Move.retrieve_id(move_id) for move_id in request_pokemon["moves"] - } - self._moves = { - move_id: move - for move_id, move in self._moves.items() - if move_id in moves_to_keep - } - if "stats" in request_pokemon: for stat in request_pokemon["stats"]: self._stats[stat] = request_pokemon["stats"][stat] @@ -816,11 +805,11 @@ def available_z_moves(self) -> List[Move]: if type_: return [ move - for move in self._moves.values() + for move in self.moves.values() if move.type == type_ and move.can_z_move ] - elif move in self._moves: - return [self._moves[move]] + elif move in self.moves: + return [self.moves[move]] return [] @property @@ -846,7 +835,11 @@ def base_stats(self) -> Dict[str, int]: :return: The pokemon's base stats. :rtype: Dict[str, int] """ - return self._base_stats + return ( + self._temporary_base_stats + if self._temporary_base_stats is not None + else self._base_stats + ) @property def boosts(self) -> Dict[str, int]: @@ -1004,7 +997,16 @@ def moves(self) -> Dict[str, Move]: :return: A dictionary of the pokemon's known moves. :rtype: Dict[str, Move] """ - return self._moves + return ( + self._temporary_moves if self._temporary_moves is not None else self._moves + ) + + @moves.setter + def moves(self, move_dict: Dict[str, Move]): + if self._temporary_moves is not None: + self._temporary_moves = move_dict + else: + self._moves = move_dict @property def must_recharge(self) -> bool: