mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-10-06 04:24:44 -07:00
Pokemon Emerald: Fix dexsanity encounters using non-enabled encounter types for logical access (#6161)
This commit is contained in:
1 parent
6f3cd85690
commit
c6697337bb
10 files changed
+124
-59
No files matched your search
@@ -1,3 +1,16 @@
|
||||
# 2.6.0
|
||||
|
||||
### Features
|
||||
|
||||
- Added `dexsanity_encounter_types` and `world_version` to slot data for trackers.
|
||||
|
||||
# 2.5.1
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fixed dexsanity logic to correctly account only for catching species in their enabled encounter types, even if they
|
||||
can be found elsewhere.
|
||||
|
||||
# 2.5.0
|
||||
|
||||
### Features
|
||||
|
||||
@@ -8,16 +8,18 @@ import os
|
||||
import pkgutil
|
||||
from typing import Any, Set, List, Dict, Optional, Tuple, ClassVar, TextIO, Union
|
||||
|
||||
from BaseClasses import CollectionState, ItemClassification, MultiWorld, Tutorial, LocationProgressType
|
||||
from BaseClasses import CollectionState, Item, ItemClassification, MultiWorld, Tutorial, LocationProgressType
|
||||
from Fill import FillError, fill_restrictive
|
||||
from Options import OptionError, Toggle
|
||||
import settings
|
||||
from worlds.AutoWorld import WebWorld, World
|
||||
|
||||
from .client import PokemonEmeraldClient # Unused, but required to register with BizHawkClient
|
||||
from .data import LEGENDARY_POKEMON, MapData, SpeciesData, TrainerData, LocationCategory, data as emerald_data
|
||||
from .data import (LEGENDARY_POKEMON, PokemonSource, MapData, SpeciesData, TrainerData, LocationCategory,
|
||||
data as emerald_data)
|
||||
from .groups import ITEM_GROUPS, LOCATION_GROUPS
|
||||
from .items import PokemonEmeraldItem, create_item_label_to_code_map, get_item_classification, offset_item_value
|
||||
from .items import (PokemonEmeraldItem, PokemonEmeraldObtainPokemonEventItem, create_item_label_to_code_map,
|
||||
get_item_classification, offset_item_value)
|
||||
from .locations import (PokemonEmeraldLocation, create_location_label_to_id_map, create_locations_by_category,
|
||||
set_free_fly, set_legendary_cave_entrances)
|
||||
from .opponents import randomize_opponent_parties
|
||||
@@ -124,6 +126,7 @@ class PokemonEmeraldWorld(World):
|
||||
blacklisted_starters: Set[int]
|
||||
blacklisted_opponent_pokemon: Set[int]
|
||||
allowed_dexsanity_species: set[int]
|
||||
enabled_dexsanity_encounter_types: set[PokemonSource]
|
||||
hm_requirements: Dict[str, Union[int, List[str]]]
|
||||
auth: bytes
|
||||
|
||||
@@ -144,6 +147,7 @@ class PokemonEmeraldWorld(World):
|
||||
self.blacklisted_starters = set()
|
||||
self.blacklisted_opponent_pokemon = set()
|
||||
self.allowed_dexsanity_species = set()
|
||||
self.enabled_dexsanity_encounter_types = set()
|
||||
self.modified_maps = copy.deepcopy(emerald_data.maps)
|
||||
self.modified_species = copy.deepcopy(emerald_data.species)
|
||||
self.modified_tmhm_moves = []
|
||||
@@ -201,6 +205,16 @@ class PokemonEmeraldWorld(World):
|
||||
if "_Legendaries" in self.options.trainer_party_blacklist.value:
|
||||
self.blacklisted_opponent_pokemon |= LEGENDARY_POKEMON
|
||||
|
||||
encounter_table = {
|
||||
"Land": PokemonSource.LAND,
|
||||
"Water": PokemonSource.WATER,
|
||||
"Fishing": PokemonSource.FISHING,
|
||||
}
|
||||
self.enabled_dexsanity_encounter_types = {
|
||||
encounter_table[encounter_type]
|
||||
for encounter_type in self.options.dexsanity_encounter_types.value
|
||||
}
|
||||
|
||||
# In race mode we don't patch any item location information into the ROM
|
||||
if self.multiworld.is_race and not self.options.remote_items:
|
||||
logging.warning("Pokemon Emerald: Forcing player %s (%s) to use remote items due to race mode.",
|
||||
@@ -739,9 +753,11 @@ class PokemonEmeraldWorld(World):
|
||||
"modify_118",
|
||||
"death_link",
|
||||
"normalize_encounter_rates",
|
||||
"dexsanity_encounter_types",
|
||||
)
|
||||
slot_data["free_fly_location_id"] = self.free_fly_location_id
|
||||
slot_data["hm_requirements"] = self.hm_requirements
|
||||
slot_data["world_version"] = self.world_version
|
||||
return slot_data
|
||||
|
||||
def create_item(self, name: str) -> PokemonEmeraldItem:
|
||||
@@ -762,3 +778,31 @@ class PokemonEmeraldWorld(World):
|
||||
None,
|
||||
self.player
|
||||
)
|
||||
|
||||
def collect(self, state: CollectionState, item: Item) -> bool:
|
||||
changed = super().collect(state, item)
|
||||
if changed:
|
||||
if isinstance(item, PokemonEmeraldObtainPokemonEventItem):
|
||||
if item.source in self.enabled_dexsanity_encounter_types:
|
||||
state.prog_items[self.player].update({
|
||||
f"DEXSANITY_{emerald_data.species[item.species].name}": 1,
|
||||
})
|
||||
if item.species in (emerald_data.constants["SPECIES_WAILORD"], emerald_data.constants["SPECIES_RELICANTH"]):
|
||||
state.prog_items[self.player].update({
|
||||
f"REGI_WALL_{emerald_data.species[item.species].name}": 1,
|
||||
})
|
||||
return changed
|
||||
|
||||
def remove(self, state: CollectionState, item: Item) -> bool:
|
||||
changed = super().remove(state, item)
|
||||
if changed:
|
||||
if isinstance(item, PokemonEmeraldObtainPokemonEventItem):
|
||||
if item.source in self.enabled_dexsanity_encounter_types:
|
||||
state.prog_items[self.player].subtract({
|
||||
f"DEXSANITY_{emerald_data.species[item.species].name}": 1,
|
||||
})
|
||||
if item.species in (emerald_data.constants["SPECIES_WAILORD"], emerald_data.constants["SPECIES_RELICANTH"]):
|
||||
state.prog_items[self.player].subtract({
|
||||
f"REGI_WALL_{emerald_data.species[item.species].name}": 1,
|
||||
})
|
||||
return changed
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"game": "Pokemon Emerald",
|
||||
"world_version": "2.5.0",
|
||||
"world_version": "2.6.0",
|
||||
"minimum_ap_version": "0.6.1",
|
||||
"authors": ["Zunawe"]
|
||||
}
|
||||
@@ -5,7 +5,7 @@ defined data (like location labels or usable pokemon species), some cleanup
|
||||
and sorting, and Warp methods.
|
||||
"""
|
||||
from dataclasses import dataclass
|
||||
from enum import IntEnum, Enum
|
||||
from enum import IntEnum, StrEnum
|
||||
import orjson
|
||||
from typing import Dict, List, NamedTuple, Optional, Set, FrozenSet, Tuple, Any, Union
|
||||
import pkgutil
|
||||
@@ -148,8 +148,7 @@ class EncounterTableData(NamedTuple):
|
||||
address: int
|
||||
|
||||
|
||||
# class EncounterType(StrEnum): # StrEnum introduced in python 3.11
|
||||
class EncounterType(Enum):
|
||||
class PokemonSource(StrEnum):
|
||||
LAND = "LAND"
|
||||
WATER = "WATER"
|
||||
FISHING = "FISHING"
|
||||
@@ -161,7 +160,7 @@ class MapData:
|
||||
name: str
|
||||
label: str
|
||||
header_address: int
|
||||
encounters: Dict[EncounterType, EncounterTableData]
|
||||
encounters: Dict[PokemonSource, EncounterTableData]
|
||||
|
||||
|
||||
class EventData(NamedTuple):
|
||||
@@ -354,24 +353,24 @@ def _init() -> None:
|
||||
if map_name in IGNORABLE_MAPS:
|
||||
continue
|
||||
|
||||
encounter_tables: Dict[EncounterType, EncounterTableData] = {}
|
||||
encounter_tables: Dict[PokemonSource, EncounterTableData] = {}
|
||||
if "land_encounters" in map_json:
|
||||
encounter_tables[EncounterType.LAND] = EncounterTableData(
|
||||
encounter_tables[PokemonSource.LAND] = EncounterTableData(
|
||||
map_json["land_encounters"]["slots"],
|
||||
map_json["land_encounters"]["address"]
|
||||
)
|
||||
if "water_encounters" in map_json:
|
||||
encounter_tables[EncounterType.WATER] = EncounterTableData(
|
||||
encounter_tables[PokemonSource.WATER] = EncounterTableData(
|
||||
map_json["water_encounters"]["slots"],
|
||||
map_json["water_encounters"]["address"]
|
||||
)
|
||||
if "fishing_encounters" in map_json:
|
||||
encounter_tables[EncounterType.FISHING] = EncounterTableData(
|
||||
encounter_tables[PokemonSource.FISHING] = EncounterTableData(
|
||||
map_json["fishing_encounters"]["slots"],
|
||||
map_json["fishing_encounters"]["address"]
|
||||
)
|
||||
if "rock_smash_encounters" in map_json:
|
||||
encounter_tables[EncounterType.ROCK_SMASH] = EncounterTableData(
|
||||
encounter_tables[PokemonSource.ROCK_SMASH] = EncounterTableData(
|
||||
map_json["rock_smash_encounters"]["slots"],
|
||||
map_json["rock_smash_encounters"]["address"]
|
||||
)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"""
|
||||
Classes and functions related to AP items for Pokemon Emerald
|
||||
"""
|
||||
from typing import Dict, FrozenSet, Set, Optional
|
||||
from typing import Dict, FrozenSet, Optional
|
||||
|
||||
from BaseClasses import Item, ItemClassification
|
||||
|
||||
from .data import BASE_OFFSET, data
|
||||
from .data import BASE_OFFSET, PokemonSource, data
|
||||
|
||||
|
||||
class PokemonEmeraldItem(Item):
|
||||
@@ -21,6 +21,20 @@ class PokemonEmeraldItem(Item):
|
||||
self.tags = data.items[reverse_offset_item_value(code)].tags
|
||||
|
||||
|
||||
class PokemonEmeraldObtainPokemonEventItem(PokemonEmeraldItem):
|
||||
source: PokemonSource
|
||||
species: int
|
||||
|
||||
def __init__(self, player: int, source: PokemonSource, species: int) -> None:
|
||||
super().__init__("", ItemClassification.progression, None, player)
|
||||
self.replace_species(species)
|
||||
self.source = source
|
||||
|
||||
def replace_species(self, new_species: int):
|
||||
self.species = new_species
|
||||
self.name = f"OBTAIN_{data.species[new_species].name}"
|
||||
|
||||
|
||||
def offset_item_value(item_value: int) -> int:
|
||||
"""
|
||||
Returns the AP item id (code) for a given item value
|
||||
|
||||
@@ -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, OptionList)
|
||||
PerGameCommonOptions, OptionGroup, StartInventory)
|
||||
|
||||
from .data import data
|
||||
|
||||
@@ -129,14 +129,14 @@ class Dexsanity(Toggle):
|
||||
display_name = "Dexsanity"
|
||||
|
||||
|
||||
class DexsanityEncounterTypes(OptionList):
|
||||
class DexsanityEncounterTypes(OptionSet):
|
||||
"""
|
||||
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"}
|
||||
valid_keys = ["Land", "Water", "Fishing"]
|
||||
default = valid_keys.copy()
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@ Functions related to pokemon species and moves
|
||||
import functools
|
||||
from typing import TYPE_CHECKING, Dict, List, Set, Optional, Tuple
|
||||
|
||||
from .data import (NUM_REAL_SPECIES, OUT_OF_LOGIC_MAPS, EncounterType, EncounterTableData, LearnsetMove, SpeciesData,
|
||||
from .data import (NUM_REAL_SPECIES, OUT_OF_LOGIC_MAPS, PokemonSource, EncounterTableData, LearnsetMove, SpeciesData,
|
||||
MapData, data)
|
||||
from .items import PokemonEmeraldObtainPokemonEventItem
|
||||
from .options import (Goal, HmCompatibility, LevelUpMoves, RandomizeAbilities, RandomizeLegendaryEncounters,
|
||||
RandomizeMiscPokemon, RandomizeStarters, RandomizeTypes, RandomizeWildPokemon,
|
||||
TmTutorCompatibility)
|
||||
@@ -227,14 +228,14 @@ def randomize_types(world: "PokemonEmeraldWorld") -> None:
|
||||
evolutions += [world.modified_species[evo.species_id] for evo in evolution.evolutions]
|
||||
|
||||
|
||||
_encounter_subcategory_ranges: Dict[EncounterType, Dict[range, Optional[str]]] = {
|
||||
EncounterType.LAND: {range(0, 12): None},
|
||||
EncounterType.WATER: {range(0, 5): None},
|
||||
EncounterType.FISHING: {range(0, 2): "OLD_ROD", range(2, 5): "GOOD_ROD", range(5, 10): "SUPER_ROD"},
|
||||
_encounter_subcategory_ranges: Dict[PokemonSource, Dict[range, Optional[str]]] = {
|
||||
PokemonSource.LAND: {range(0, 12): None},
|
||||
PokemonSource.WATER: {range(0, 5): None},
|
||||
PokemonSource.FISHING: {range(0, 2): "OLD_ROD", range(2, 5): "GOOD_ROD", range(5, 10): "SUPER_ROD"},
|
||||
}
|
||||
|
||||
|
||||
def _rename_wild_events(world: "PokemonEmeraldWorld", map_data: MapData, new_slots: List[int], encounter_type: EncounterType):
|
||||
def _adjust_wild_events(world: "PokemonEmeraldWorld", map_data: MapData, new_slots: List[int], encounter_type: PokemonSource):
|
||||
"""
|
||||
Renames the events that correspond to wild encounters to reflect the new species there after randomization
|
||||
"""
|
||||
@@ -254,22 +255,17 @@ def _rename_wild_events(world: "PokemonEmeraldWorld", map_data: MapData, new_slo
|
||||
# Fishing locations include the rod name
|
||||
subcategory_str = "" if subcategory_name is None else "_" + subcategory_name
|
||||
encounter_location_index = subcategory_species.index(new_species_id) + 1
|
||||
encounter_location_name = f"{map_data.name}_{encounter_type.value}_ENCOUNTERS{subcategory_str}_{encounter_location_index}"
|
||||
encounter_location_name = f"{map_data.name}_{encounter_type}_ENCOUNTERS{subcategory_str}_{encounter_location_index}"
|
||||
try:
|
||||
# Get the corresponding location and change the event name to reflect the new species
|
||||
slot_location = world.multiworld.get_location(encounter_location_name, world.player)
|
||||
slot_location.item.name = f"CATCH_{data.species[new_species_id].name}"
|
||||
assert isinstance(slot_location.item, PokemonEmeraldObtainPokemonEventItem)
|
||||
slot_location.item.replace_species(new_species_id)
|
||||
except KeyError:
|
||||
pass # Map probably isn't included; should be careful here about bad encounter location names
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -296,7 +292,7 @@ def randomize_wild_encounters(world: "PokemonEmeraldWorld") -> None:
|
||||
placed_priority_species = False
|
||||
map_data = world.modified_maps[map_name]
|
||||
|
||||
new_encounters: Dict[EncounterType, EncounterTableData] = {}
|
||||
new_encounters: Dict[PokemonSource, EncounterTableData] = {}
|
||||
|
||||
for encounter_type, table in map_data.encounters.items():
|
||||
# Create a map from the original species to new species
|
||||
@@ -306,7 +302,7 @@ def randomize_wild_encounters(world: "PokemonEmeraldWorld") -> None:
|
||||
for species_id in table.slots:
|
||||
if species_id not in species_old_to_new_map:
|
||||
if not placed_priority_species and len(priority_species) > 0 \
|
||||
and encounter_type != EncounterType.ROCK_SMASH and map_name not in OUT_OF_LOGIC_MAPS:
|
||||
and encounter_type != PokemonSource.ROCK_SMASH and map_name not in OUT_OF_LOGIC_MAPS:
|
||||
new_species_id = priority_species.pop()
|
||||
placed_priority_species = True
|
||||
else:
|
||||
@@ -370,7 +366,7 @@ def randomize_wild_encounters(world: "PokemonEmeraldWorld") -> None:
|
||||
|
||||
species_old_to_new_map[species_id] = new_species_id
|
||||
|
||||
if world.options.dexsanity and encounter_type != EncounterType.ROCK_SMASH \
|
||||
if world.options.dexsanity and encounter_type != PokemonSource.ROCK_SMASH \
|
||||
and map_name not in OUT_OF_LOGIC_MAPS and new_species_id not in world.blacklisted_wilds:
|
||||
already_placed.add(new_species_id)
|
||||
|
||||
@@ -378,14 +374,14 @@ def randomize_wild_encounters(world: "PokemonEmeraldWorld") -> None:
|
||||
new_slots: List[int] = []
|
||||
for species_id in table.slots:
|
||||
new_slots.append(species_old_to_new_map[species_id])
|
||||
if encounter_type in enabled_encounters:
|
||||
if encounter_type in world.enabled_dexsanity_encounter_types:
|
||||
world.allowed_dexsanity_species.update(new_slots)
|
||||
|
||||
new_encounters[encounter_type] = EncounterTableData(new_slots, table.address)
|
||||
|
||||
# Rock smash encounters not used in logic, so they have no events
|
||||
if encounter_type != EncounterType.ROCK_SMASH:
|
||||
_rename_wild_events(world, map_data, new_slots, encounter_type)
|
||||
if encounter_type != PokemonSource.ROCK_SMASH:
|
||||
_adjust_wild_events(world, map_data, new_slots, encounter_type)
|
||||
|
||||
map_data.encounters = new_encounters
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple
|
||||
|
||||
from BaseClasses import CollectionState, ItemClassification, Region
|
||||
|
||||
from .data import EncounterType, data
|
||||
from .items import PokemonEmeraldItem
|
||||
from .data import PokemonSource, data
|
||||
from .items import PokemonEmeraldItem, PokemonEmeraldObtainPokemonEventItem
|
||||
from .locations import PokemonEmeraldLocation
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -20,10 +20,10 @@ def create_regions(world: "PokemonEmeraldWorld") -> Dict[str, Region]:
|
||||
"""
|
||||
# Used in connect_to_map_encounters. Splits encounter categories into "subcategories" and gives them names
|
||||
# and rules so the rods can only access their specific slots. Rock smash encounters are not considered in logic.
|
||||
encounter_categories: Dict[EncounterType, List[Tuple[Optional[str], range, Optional[Callable[[CollectionState], bool]]]]] = {
|
||||
EncounterType.LAND: [(None, range(0, 12), None)],
|
||||
EncounterType.WATER: [(None, range(0, 5), None)],
|
||||
EncounterType.FISHING: [
|
||||
encounter_categories: Dict[PokemonSource, List[Tuple[Optional[str], range, Optional[Callable[[CollectionState], bool]]]]] = {
|
||||
PokemonSource.LAND: [(None, range(0, 12), None)],
|
||||
PokemonSource.WATER: [(None, range(0, 5), None)],
|
||||
PokemonSource.FISHING: [
|
||||
("OLD_ROD", range(0, 2), lambda state: state.has("Old Rod", world.player)),
|
||||
("GOOD_ROD", range(2, 5), lambda state: state.has("Good Rod", world.player)),
|
||||
("SUPER_ROD", range(5, 10), lambda state: state.has("Super Rod", world.player)),
|
||||
@@ -43,7 +43,7 @@ def create_regions(world: "PokemonEmeraldWorld") -> Dict[str, Region]:
|
||||
# For each of land, water, and fishing, connect the region if indicated by include_slots
|
||||
for i, (encounter_type, subcategories) in enumerate(encounter_categories.items()):
|
||||
if include_slots[i]:
|
||||
region_name = f"{map_name}_{encounter_type.value}_ENCOUNTERS"
|
||||
region_name = f"{map_name}_{encounter_type}_ENCOUNTERS"
|
||||
|
||||
# If the region hasn't been created yet, create it now
|
||||
try:
|
||||
@@ -56,7 +56,7 @@ def create_regions(world: "PokemonEmeraldWorld") -> Dict[str, Region]:
|
||||
for subcategory in subcategories:
|
||||
# Want to create locations per species, not per slot
|
||||
# encounter_categories includes info on which slots belong to which subcategory
|
||||
unique_species = []
|
||||
unique_species: list[int] = []
|
||||
for j, species_id in enumerate(encounter_slots):
|
||||
if j in subcategory[1] and not species_id in unique_species:
|
||||
unique_species.append(species_id)
|
||||
@@ -76,11 +76,10 @@ def create_regions(world: "PokemonEmeraldWorld") -> Dict[str, Region]:
|
||||
encounter_location.access_rule = subcategory[2]
|
||||
|
||||
# Fill the location with an event for catching that species
|
||||
encounter_location.place_locked_item(PokemonEmeraldItem(
|
||||
f"CATCH_{data.species[species_id].name}",
|
||||
ItemClassification.progression_skip_balancing,
|
||||
None,
|
||||
world.player
|
||||
encounter_location.place_locked_item(PokemonEmeraldObtainPokemonEventItem(
|
||||
world.player,
|
||||
encounter_type,
|
||||
species_id,
|
||||
))
|
||||
encounter_region.locations.append(encounter_location)
|
||||
|
||||
|
||||
@@ -586,7 +586,7 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
|
||||
entrance_rules["REGION_SKY_PILLAR_4F/MAIN -> REGION_SKY_PILLAR_4F/ABOVE_3F_TOP_CENTER"] = Has("Mach Bike")
|
||||
|
||||
# Route 134
|
||||
location_rules["EVENT_UNDO_REGI_SEAL"] = HasAll("CATCH_SPECIES_WAILORD", "CATCH_SPECIES_RELICANTH")
|
||||
location_rules["EVENT_UNDO_REGI_SEAL"] = HasAll("REGI_WALL_SPECIES_WAILORD", "REGI_WALL_SPECIES_RELICANTH")
|
||||
|
||||
entrance_rules["REGION_ROUTE134/MAIN -> REGION_UNDERWATER_ROUTE134/MAIN"] = hm_rules["HM08 Dive"]
|
||||
entrance_rules["REGION_SEALED_CHAMBER_OUTER_ROOM/MAIN -> REGION_SEALED_CHAMBER_OUTER_ROOM/CRUMBLED_WALL"] = Has("EVENT_MOVE_TUTOR_DIG")
|
||||
@@ -637,7 +637,7 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
|
||||
if species.species_id in world.blacklisted_wilds or species.species_id not in world.allowed_dexsanity_species:
|
||||
continue
|
||||
|
||||
location_rules[f"Pokedex - {species.label}"] = Has(f"CATCH_{species.name}")
|
||||
location_rules[f"Pokedex - {species.label}"] = Has(f"DEXSANITY_{species.name}")
|
||||
|
||||
# Legendary hunt prevents Latios from being a wild spawn so the roamer
|
||||
# can be tracked, and also guarantees that the roamer is a Latios.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import orjson
|
||||
from typing import Any, Dict, List, Optional, Tuple, Iterable
|
||||
|
||||
from .data import NATIONAL_ID_TO_SPECIES_ID, EncounterType, data
|
||||
from .data import NATIONAL_ID_TO_SPECIES_ID, PokemonSource, data
|
||||
|
||||
|
||||
CHARACTER_DECODING_MAP = {
|
||||
@@ -86,8 +86,8 @@ def decode_string(string_data: Iterable[int]) -> str:
|
||||
return string
|
||||
|
||||
|
||||
def get_encounter_type_label(encounter_type: EncounterType, slot: int) -> str:
|
||||
if encounter_type == EncounterType.FISHING:
|
||||
def get_encounter_type_label(encounter_type: PokemonSource, slot: int) -> str:
|
||||
if encounter_type == PokemonSource.FISHING:
|
||||
return {
|
||||
0: "Old Rod",
|
||||
1: "Old Rod",
|
||||
@@ -102,9 +102,9 @@ def get_encounter_type_label(encounter_type: EncounterType, slot: int) -> str:
|
||||
}[slot]
|
||||
|
||||
return {
|
||||
EncounterType.LAND: 'Land',
|
||||
EncounterType.WATER: 'Water',
|
||||
EncounterType.ROCK_SMASH: 'Rock Smash',
|
||||
PokemonSource.LAND: 'Land',
|
||||
PokemonSource.WATER: 'Water',
|
||||
PokemonSource.ROCK_SMASH: 'Rock Smash',
|
||||
}[encounter_type]
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user