diff --git a/worlds/pokemon_emerald/__init__.py b/worlds/pokemon_emerald/__init__.py index 4f2c2ef95c..10abed539f 100644 --- a/worlds/pokemon_emerald/__init__.py +++ b/worlds/pokemon_emerald/__init__.py @@ -123,6 +123,7 @@ class PokemonEmeraldWorld(World): blacklisted_wilds: Set[int] blacklisted_starters: Set[int] blacklisted_opponent_pokemon: Set[int] + allowed_dexsanity_species: set[int] hm_requirements: Dict[str, Union[int, List[str]]] auth: bytes @@ -142,6 +143,7 @@ class PokemonEmeraldWorld(World): self.blacklisted_wilds = set() self.blacklisted_starters = set() self.blacklisted_opponent_pokemon = set() + self.allowed_dexsanity_species = set() self.modified_maps = copy.deepcopy(emerald_data.maps) self.modified_species = copy.deepcopy(emerald_data.species) self.modified_tmhm_moves = [] @@ -265,6 +267,7 @@ class PokemonEmeraldWorld(World): from .regions import create_regions all_regions = create_regions(self) + randomize_wild_encounters(self) # Categories with progression items always included categories = { LocationCategory.BADGE, @@ -494,7 +497,6 @@ class PokemonEmeraldWorld(World): set_rules(self) def connect_entrances(self): - randomize_wild_encounters(self) self.shuffle_badges_hms() # For entrance randomization, disconnect entrances here, randomize map, then # undo badge/HM placement and re-shuffle them in the new map. diff --git a/worlds/pokemon_emerald/locations.py b/worlds/pokemon_emerald/locations.py index 49ce147041..fd8d0ebc7d 100644 --- a/worlds/pokemon_emerald/locations.py +++ b/worlds/pokemon_emerald/locations.py @@ -110,7 +110,7 @@ def create_locations_by_category(world: "PokemonEmeraldWorld", regions: Dict[str national_dex_id = int(location_name[-3:]) # Location names are formatted POKEDEX_REWARD_### # Don't create this pokedex location if player can't find it in the wild - if NATIONAL_ID_TO_SPECIES_ID[national_dex_id] in world.blacklisted_wilds: + if NATIONAL_ID_TO_SPECIES_ID[national_dex_id] in world.blacklisted_wilds or NATIONAL_ID_TO_SPECIES_ID[national_dex_id] not in world.allowed_dexsanity_species: continue location_id += POKEDEX_OFFSET + national_dex_id diff --git a/worlds/pokemon_emerald/options.py b/worlds/pokemon_emerald/options.py index 29929bd672..9529be877e 100644 --- a/worlds/pokemon_emerald/options.py +++ b/worlds/pokemon_emerald/options.py @@ -4,7 +4,7 @@ Option definitions for Pokemon Emerald from dataclasses import dataclass from Options import (Choice, DeathLink, DefaultOnToggle, OptionSet, NamedRange, Range, Toggle, FreeText, - PerGameCommonOptions, OptionGroup, StartInventory) + PerGameCommonOptions, OptionGroup, StartInventory, OptionList) from .data import data @@ -129,6 +129,17 @@ class Dexsanity(Toggle): display_name = "Dexsanity" +class DexsanityEncounterTypes(OptionList): + """ + Determines which Dexsanity encounter areas are in logic. + + Logic will only consider access to Pokemon at these encounter types, but they may still be found elsewhere. + """ + display_name = "Dexsanity Encounter Types" + valid_keys = {"Land", "Water", "Fishing"} + default = valid_keys.copy() + + class Trainersanity(Toggle): """ Defeating a trainer gives you an item. @@ -870,6 +881,7 @@ class PokemonEmeraldOptions(PerGameCommonOptions): npc_gifts: RandomizeNpcGifts berry_trees: RandomizeBerryTrees dexsanity: Dexsanity + dexsanity_encounter_types: DexsanityEncounterTypes trainersanity: Trainersanity item_pool_type: ItemPoolType diff --git a/worlds/pokemon_emerald/pokemon.py b/worlds/pokemon_emerald/pokemon.py index 8f799ce611..73af6c4658 100644 --- a/worlds/pokemon_emerald/pokemon.py +++ b/worlds/pokemon_emerald/pokemon.py @@ -264,6 +264,12 @@ def _rename_wild_events(world: "PokemonEmeraldWorld", map_data: MapData, new_slo def randomize_wild_encounters(world: "PokemonEmeraldWorld") -> None: + encounter_table = { + "Land": EncounterType.LAND, + "Water": EncounterType.WATER, + "Fishing": EncounterType.FISHING, + } + enabled_encounters = {encounter_table[encounter_type] for encounter_type in world.options.dexsanity_encounter_types.value} if world.options.wild_pokemon == RandomizeWildPokemon.option_vanilla: return @@ -370,6 +376,8 @@ def randomize_wild_encounters(world: "PokemonEmeraldWorld") -> None: # Actually create the new list of slots and encounter table new_slots: List[int] = [] + if encounter_type in enabled_encounters: + world.allowed_dexsanity_species.update(table.slots) for species_id in table.slots: new_slots.append(species_old_to_new_map[species_id]) diff --git a/worlds/pokemon_emerald/rules.py b/worlds/pokemon_emerald/rules.py index 828eb20f72..eeadb8bea2 100644 --- a/worlds/pokemon_emerald/rules.py +++ b/worlds/pokemon_emerald/rules.py @@ -1548,7 +1548,7 @@ def set_rules(world: "PokemonEmeraldWorld") -> None: for i in range(NUM_REAL_SPECIES): species = data.species[NATIONAL_ID_TO_SPECIES_ID[i + 1]] - if species.species_id in world.blacklisted_wilds: + if species.species_id in world.blacklisted_wilds or species.species_id not in world.allowed_dexsanity_species: continue set_rule(