diff --git a/modules/modes/safari.py b/modules/modes/safari.py index b005f80a..aa433d3b 100644 --- a/modules/modes/safari.py +++ b/modules/modes/safari.py @@ -6,7 +6,7 @@ from modules.map_data import MapFRLG from modules.player import get_player, get_player_avatar from modules.pokemon_party import get_party -from modules.pokemon import get_species_by_name +from modules.pokemon import get_species_by_name, get_opponent from modules.memory import get_event_flag from modules.menuing import StartMenuNavigator from modules.modes.util.walking import wait_for_player_avatar_to_be_controllable @@ -52,8 +52,9 @@ def __init__(self): self._should_reset = False self._should_reenter = False self._atleast_one_pokemon_catched = False + self._target_caught = False self._use_repel = False - self._money_spent_limit = 2000 + self._money_spent_limit = 25000 @staticmethod def name() -> str: @@ -69,6 +70,9 @@ def on_battle_ended(self, outcome: "BattleOutcome") -> None: update flags to manage the re-entry or reset logic. """ if outcome is BattleOutcome.Caught: + catched_pokemon = get_opponent().species.name + if catched_pokemon == self._target_pokemon: + self._target_caught = True self._atleast_one_pokemon_catched = True if get_safari_balls_left() < 30: current_cash = get_player().money @@ -88,9 +92,9 @@ def run(self) -> Generator: pokemon_choices = [] for safari_pokemon in SafariPokemon.available_pokemon(context.rom): - species = get_species_by_name(safari_pokemon.value.name) + species = safari_pokemon.value.species sprite_path = get_regular_sprite(species) - pokemon_choices.append(Selection(f"{safari_pokemon.value.name}", sprite_path)) + pokemon_choices.append(Selection(f"{safari_pokemon.value.species.name}", sprite_path)) pokemon_choice = ask_for_choice_scroll( choices=pokemon_choices, @@ -105,10 +109,11 @@ def run(self) -> Generator: yield return - self._target_pokemon = get_safari_pokemon(pokemon_choice) - self._check_mode_requirement(self._target_pokemon.value.mode, self._target_pokemon.value.hunting_object) + target = get_safari_pokemon(pokemon_choice) + self._target_pokemon = target.value.species.name + self._check_mode_requirement(target.value.mode, target.value.hunting_object) - if self._target_pokemon.value.mode != SafariHuntingMode.FISHING: + if target.value.mode != SafariHuntingMode.FISHING: mode = ask_for_choice( [ Selection("Use Repel", get_sprites_path() / "items" / "Repel.png"), @@ -125,22 +130,28 @@ def run(self) -> Generator: if mode == "Use Repel": self._use_repel = True - if self._target_pokemon.value.hunting_object: - yield from register_key_item(get_item_by_name(self._target_pokemon.value.hunting_object)) + if target.value.hunting_object: + yield from register_key_item(get_item_by_name(target.value.hunting_object)) while True: - if self._should_reset: + if self._target_caught: + yield from self._exit_safari_zone() + context.message = f"{self._target_pokemon} has been caught ! Save your game !" + context.set_manual_mode() + break + elif self._should_reset: if not self._atleast_one_pokemon_catched: yield from self._soft_reset() self._starting_cash = get_player().money else: yield from self._exit_safari_zone() - context.message = f"You have reached the money threshold (either out of money or have spent over {self._money_spent_limit}₽), but you've caught a Pokémon during this phase. It's recommended to save your game and restart the mode." + context.message = f"You have hit the money threshold (either you've run out of funds or spent over {self._money_spent_limit}₽), but you managed to catch at least one Pokémon during this cycle. Consider saving your game." context.set_manual_mode() - if self._should_reenter: + break + elif self._should_reenter: yield from self._re_enter_safari_zone() - yield from self._start_safari_hunt(self._target_pokemon) + yield from self._start_safari_hunt(target) def _start_safari_hunt(self, safari_pokemon: SafariPokemon) -> Generator: current_cash = get_player().money diff --git a/modules/safari_strategy.py b/modules/safari_strategy.py index 9f9f6b51..24a8e80d 100644 --- a/modules/safari_strategy.py +++ b/modules/safari_strategy.py @@ -5,11 +5,12 @@ from typing import Union, Tuple, Optional, Callable, List from modules.context import context from modules.battle_strategies import SafariTurnAction -from modules.pokemon import Pokemon +from modules.pokemon import Pokemon, Species, get_species_by_name from modules.runtime import get_data_path from modules.memory import read_symbol from modules.files import make_string_safe_for_file_name from modules.map_data import MapFRLG, MapRSE +from modules.modes._interface import BotModeError class SafariHuntingMode(Enum): @@ -27,7 +28,7 @@ class SafariHuntingObject: @dataclass(frozen=True) class SafariCatchingLocation: - name: str + species: Species map_location: Union[MapFRLG, MapRSE] tile_location: Tuple[int, int] mode: SafariHuntingMode @@ -38,29 +39,57 @@ class SafariCatchingLocation: class SafariPokemon(Enum): """Enum for Pokémon locations and strategies in the Safari Zone.""" - NIDORAN_F = SafariCatchingLocation("Nidoran♀", MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN) - NIDORINA = SafariCatchingLocation("Nidorina", MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN) - NIDORAN_M = SafariCatchingLocation("Nidoran♂", MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN) - NIDORINO = SafariCatchingLocation("Nidorino", MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN) - PARAS = SafariCatchingLocation("Paras", MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN) - PARASECT = SafariCatchingLocation("Parasect", MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN) - VENONAT = SafariCatchingLocation("Venonat", MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN) - VENOMOTH = SafariCatchingLocation("Venomoth", MapFRLG.SAFARI_ZONE_NORTH, (35, 30), SafariHuntingMode.SPIN) - DODUO = SafariCatchingLocation("Doduo", MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN) - RHYHORN = SafariCatchingLocation("Rhyhorn", MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN) - EXEGGCUTE = SafariCatchingLocation("Exeggcute", MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN) - TAUROS = SafariCatchingLocation("Tauros", MapFRLG.SAFARI_ZONE_WEST, (15, 27), SafariHuntingMode.SPIN) - CHANSEY = SafariCatchingLocation("Chansey", MapFRLG.SAFARI_ZONE_NORTH, (35, 30), SafariHuntingMode.SPIN) - KANGASKHAN = SafariCatchingLocation("Kangaskhan", MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN) + NIDORAN_F = SafariCatchingLocation( + get_species_by_name("Nidoran♀"), MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN + ) + NIDORINA = SafariCatchingLocation( + get_species_by_name("Nidorina"), MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN + ) + NIDORAN_M = SafariCatchingLocation( + get_species_by_name("Nidoran♂"), MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN + ) + NIDORINO = SafariCatchingLocation( + get_species_by_name("Nidorino"), MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN + ) + PARAS = SafariCatchingLocation( + get_species_by_name("Paras"), MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN + ) + PARASECT = SafariCatchingLocation( + get_species_by_name("Parasect"), MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN + ) + VENONAT = SafariCatchingLocation( + get_species_by_name("Venonat"), MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN + ) + VENOMOTH = SafariCatchingLocation( + get_species_by_name("Venomoth"), MapFRLG.SAFARI_ZONE_NORTH, (35, 30), SafariHuntingMode.SPIN + ) + DODUO = SafariCatchingLocation( + get_species_by_name("Doduo"), MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN + ) + RHYHORN = SafariCatchingLocation( + get_species_by_name("Rhyhorn"), MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN + ) + EXEGGCUTE = SafariCatchingLocation( + get_species_by_name("Exeggcute"), MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN + ) + TAUROS = SafariCatchingLocation( + get_species_by_name("Tauros"), MapFRLG.SAFARI_ZONE_WEST, (15, 27), SafariHuntingMode.SPIN + ) + CHANSEY = SafariCatchingLocation( + get_species_by_name("Chansey"), MapFRLG.SAFARI_ZONE_NORTH, (35, 30), SafariHuntingMode.SPIN + ) + KANGASKHAN = SafariCatchingLocation( + get_species_by_name("Kangaskhan"), MapFRLG.SAFARI_ZONE_EAST, (29, 28), SafariHuntingMode.SPIN + ) PINSIR = SafariCatchingLocation( - "Pinsir", + get_species_by_name("Pinsir"), MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN, availability=lambda rom: context.rom.is_lg, ) SCYTHER = SafariCatchingLocation( - "Scyther", + get_species_by_name("Scyther"), MapFRLG.SAFARI_ZONE_CENTER, (24, 27), SafariHuntingMode.SPIN, @@ -68,32 +97,56 @@ class SafariPokemon(Enum): ) POLIWAG = SafariCatchingLocation( - "Poliwag", MapFRLG.SAFARI_ZONE_CENTER, (32, 19), SafariHuntingMode.FISHING, SafariHuntingObject.GOOD_ROD + get_species_by_name("Poliwag"), + MapFRLG.SAFARI_ZONE_CENTER, + (32, 19), + SafariHuntingMode.FISHING, + SafariHuntingObject.GOOD_ROD, ) MAGIKARP = SafariCatchingLocation( - "Magikarp", MapFRLG.SAFARI_ZONE_CENTER, (32, 19), SafariHuntingMode.FISHING, SafariHuntingObject.OLD_ROD + get_species_by_name("Magikarp"), + MapFRLG.SAFARI_ZONE_CENTER, + (32, 19), + SafariHuntingMode.FISHING, + SafariHuntingObject.OLD_ROD, ) GOLDEEN = SafariCatchingLocation( - "Goldeen", MapFRLG.SAFARI_ZONE_CENTER, (32, 19), SafariHuntingMode.FISHING, SafariHuntingObject.GOOD_ROD + get_species_by_name("Goldeen"), + MapFRLG.SAFARI_ZONE_CENTER, + (32, 19), + SafariHuntingMode.FISHING, + SafariHuntingObject.GOOD_ROD, ) SEAKING = SafariCatchingLocation( - "Seaking", MapFRLG.SAFARI_ZONE_CENTER, (32, 19), SafariHuntingMode.FISHING, SafariHuntingObject.SUPER_ROD + get_species_by_name("Seaking"), + MapFRLG.SAFARI_ZONE_CENTER, + (32, 19), + SafariHuntingMode.FISHING, + SafariHuntingObject.SUPER_ROD, ) DRATINI = SafariCatchingLocation( - "Dratini", MapFRLG.SAFARI_ZONE_CENTER, (32, 19), SafariHuntingMode.FISHING, SafariHuntingObject.SUPER_ROD + get_species_by_name("Dratini"), + MapFRLG.SAFARI_ZONE_CENTER, + (32, 19), + SafariHuntingMode.FISHING, + SafariHuntingObject.SUPER_ROD, ) DRAGONAIR = SafariCatchingLocation( - "Dragonair", MapFRLG.SAFARI_ZONE_CENTER, (32, 19), SafariHuntingMode.FISHING, SafariHuntingObject.SUPER_ROD + get_species_by_name("Dragonair"), + MapFRLG.SAFARI_ZONE_CENTER, + (32, 19), + SafariHuntingMode.FISHING, + SafariHuntingObject.SUPER_ROD, ) PSYDUCK = SafariCatchingLocation( - "Psyduck", + get_species_by_name("Psyduck"), MapFRLG.SAFARI_ZONE_CENTER, (32, 18), SafariHuntingMode.SURF, availability=lambda rom: context.rom.is_fr, ) SLOWPOKE = SafariCatchingLocation( - "Slowpoke", + get_species_by_name("Slowpoke"), MapFRLG.SAFARI_ZONE_CENTER, (32, 18), SafariHuntingMode.SURF, @@ -272,7 +325,6 @@ def get_navigation_path( path = navigation_paths.get(target_map) if path is None: - console.print(f"Error: No navigation path defined for {target_map}.") - return [] + raise BotModeError(f"Error: No navigation path defined for {target_map}.") return path