Skip to content

Commit

Permalink
Merge branch 'frlg-dev' into frlg-stable
Browse files Browse the repository at this point in the history
  • Loading branch information
vyneras committed Jul 25, 2024
2 parents 718905c + 75ac1e0 commit 5e611a1
Show file tree
Hide file tree
Showing 21 changed files with 825 additions and 312 deletions.
72 changes: 46 additions & 26 deletions worlds/pokemon_frlg/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Archipelago World definition for Pokemon FireRed/LeafGreen
Archipelago World definition for Pokémon FireRed/LeafGreen
"""
import copy
import os.path
Expand All @@ -13,21 +13,22 @@
from Fill import fill_restrictive, FillError
from worlds.AutoWorld import WebWorld, World
from .client import PokemonFRLGClient
from .data import data as frlg_data, EventData, MapData, MiscPokemonData, SpeciesData, StarterData
from .data import data as frlg_data, EventData, MapData, MiscPokemonData, SpeciesData, StarterData, TrainerData
from .items import ITEM_GROUPS, create_item_name_to_id_map, get_item_classification, PokemonFRLGItem
from .locations import (LOCATION_GROUPS, create_location_name_to_id_map, create_locations_from_tags, set_free_fly,
PokemonFRLGLocation)
from .options import (PokemonFRLGOptions, GameVersion, RandomizeWildPokemon, ShuffleHiddenItems,
ShuffleBadges, ViridianCityRoadblock)
from .pokemon import randomize_legendaries, randomize_misc_pokemon, randomize_starters, randomize_wild_encounters
from .pokemon import (randomize_abilities, randomize_legendaries, randomize_misc_pokemon, randomize_moves,
randomize_starters, randomize_trainer_parties, randomize_types, randomize_wild_encounters)
from .rom import (write_tokens, FRLGContainer, PokemonFireRedProcedurePatch, PokemonFireRedRev1ProcedurePatch,
PokemonLeafGreenProcedurePatch, PokemonLeafGreenRev1ProcedurePatch)
from .util import int_to_bool_array, HM_TO_COMPATABILITY_ID


class PokemonFRLGWebWorld(WebWorld):
"""
Webhost info for Pokemon FireRed and LeafGreen
Webhost info for Pokémon FireRed and LeafGreen
"""
setup_en = Tutorial(
"Multiworld Setup Guide",
Expand All @@ -43,33 +44,41 @@ class PokemonFRLGWebWorld(WebWorld):

class PokemonFRLGSettings(settings.Group):
class PokemonFireRedRomFile(settings.UserFilePath):
"""File name of your English Pokemon FireRed ROM"""
"""File name of your English Pokémon FireRed ROM"""
description = "Pokemon FireRed ROM File"
copy_to = "Pokemon - FireRed Version (USA, Europe).gba"
md5s = [PokemonFireRedProcedurePatch.hash]

class PokemonFireRedRev1RomFile(settings.UserFilePath):
"""File name of your English Pokemon FireRed (Rev 1) ROM"""
"""File name of your English Pokémon FireRed (Rev 1) ROM"""
description = "Pokemon FireRed (Rev 1) ROM File"
copy_to = "Pokemon - FireRed Version (USA, Europe) (Rev 1).gba"
md5s = [PokemonFireRedRev1ProcedurePatch.hash]

class PokemonLeafGreenRomFile(settings.UserFilePath):
"""File name of your English Pokemon LeafGreen ROM"""
"""File name of your English Pokémon LeafGreen ROM"""
description = "Pokemon LeafGreen ROM File"
copy_to = "Pokemon - LeafGreen Version (USA, Europe).gba"
md5s = [PokemonLeafGreenProcedurePatch.hash]

class PokemonLeafGreenRev1RomFile(settings.UserFilePath):
"""File name of your English Pokemon LeafGreen (Rev 1) ROM"""
"""File name of your English Pokémon LeafGreen (Rev 1) ROM"""
description = "Pokemon LeafGreen (Rev 1) ROM File"
copy_to = "Pokemon - LeafGreen Version (USA, Europe) (Rev 1).gba"
md5s = [PokemonLeafGreenRev1ProcedurePatch.hash]

firered_rom_file: PokemonFireRedRomFile = PokemonFireRedRomFile(PokemonFireRedRomFile.copy_to)
firered_rev1_rom_file: PokemonFireRedRev1RomFile = PokemonFireRedRev1RomFile(PokemonFireRedRev1RomFile.copy_to)
leafgreen_rom_file: PokemonLeafGreenRomFile = PokemonLeafGreenRomFile(PokemonLeafGreenRomFile.copy_to)
leafgreen_rev1_rom_file: PokemonLeafGreenRev1RomFile = PokemonLeafGreenRev1RomFile(PokemonLeafGreenRev1RomFile.copy_to)
firered_rom_file: PokemonFireRedRomFile = PokemonFireRedRomFile(
PokemonFireRedRomFile.copy_to
)
firered_rev1_rom_file: PokemonFireRedRev1RomFile = PokemonFireRedRev1RomFile(
PokemonFireRedRev1RomFile.copy_to
)
leafgreen_rom_file: PokemonLeafGreenRomFile = PokemonLeafGreenRomFile(
PokemonLeafGreenRomFile.copy_to
)
leafgreen_rev1_rom_file: PokemonLeafGreenRev1RomFile = PokemonLeafGreenRev1RomFile(
PokemonLeafGreenRev1RomFile.copy_to
)


class PokemonFRLGWorld(World):
Expand Down Expand Up @@ -103,7 +112,9 @@ class PokemonFRLGWorld(World):
modified_events: Dict[str, EventData]
modified_legendary_pokemon: Dict[str, MiscPokemonData]
modified_misc_pokemon: Dict[str, MiscPokemonData]
modified_trainers: Dict[int, TrainerData]
hm_compatability: Dict[str, List[str]]
per_species_tmhm_moves: Dict[int, List[int]]
trade_pokemon: List[Tuple[str, str]]
auth: bytes

Expand All @@ -116,7 +127,9 @@ def __init__(self, multiworld, player):
self.modified_events = copy.deepcopy(frlg_data.events)
self.modified_legendary_pokemon = copy.deepcopy(frlg_data.legendary_pokemon)
self.modified_misc_pokemon = copy.deepcopy(frlg_data.misc_pokemon)
self.modified_trainers = copy.deepcopy(frlg_data.trainers)
self.hm_compatability = {}
self.per_species_tmhm_moves = {}
self.trade_pokemon = list()

@classmethod
Expand All @@ -128,6 +141,14 @@ def stage_assert_generate(cls, multiworld: MultiWorld) -> None:
def get_filler_item_name(self) -> str:
return "Poke Ball"

def generate_early(self) -> None:
randomize_types(self)
randomize_wild_encounters(self)
randomize_starters(self)
randomize_legendaries(self)
randomize_misc_pokemon(self)
self._create_hm_compatability_dict()

def create_regions(self) -> None:
from .regions import create_regions

Expand All @@ -154,13 +175,6 @@ def create_items(self) -> None:
itempool = [self.create_item_by_id(location.default_item_id) for location in item_locations]
self.multiworld.itempool += itempool

def generate_early(self) -> None:
randomize_wild_encounters(self)
randomize_starters(self)
randomize_legendaries(self)
randomize_misc_pokemon(self)
self.create_hm_compatability_dict()

def set_rules(self) -> None:
from .rules import set_rules
set_rules(self)
Expand Down Expand Up @@ -218,6 +232,10 @@ def generate_output(self, output_directory: str) -> None:
for species in self.modified_species.values():
species.catch_rate = max(species.catch_rate, min_catch_rate)

randomize_abilities(self)
randomize_moves(self)
randomize_trainer_parties(self)

if self.options.game_version == GameVersion.option_firered:
patch_rev0 = PokemonFireRedProcedurePatch(player=self.player, player_name=self.player_name)
patch_rev0.write_file("base_patch_firered.bsdiff4",
Expand All @@ -240,9 +258,11 @@ def generate_output(self, output_directory: str) -> None:
out_file_name = self.multiworld.get_out_file_name_base(self.player)
output = tempfile.TemporaryDirectory()
with output as temp_dir:
patch_rev0.write(os.path.join(temp_dir, f'{out_file_name}{patch_rev0.patch_file_ending}'))
patch_rev1.write(os.path.join(temp_dir, f'{out_file_name}{patch_rev1.patch_file_ending}'))
zip_file_name = f"AP-{self.multiworld.seed_name}-P{self.player}-{self.multiworld.get_file_safe_player_name(self.player)}"
patch_rev0.write(os.path.join(temp_dir, f"{out_file_name}{patch_rev0.patch_file_ending}"))
patch_rev1.write(os.path.join(temp_dir, f"{out_file_name}{patch_rev1.patch_file_ending}"))
seed_name = self.multiworld.seed_name
player_name = self.multiworld.get_file_safe_player_name(self.player)
zip_file_name = f"AP-{seed_name}-P{self.player}-{player_name}"
frlg_container = FRLGContainer(temp_dir,
os.path.join(output_directory, zip_file_name + "_" + Utils.__version__),
self.player,
Expand All @@ -259,7 +279,7 @@ def generate_output(self, output_directory: str) -> None:

@classmethod
def stage_post_fill(cls, multiworld):
# Change all but one instance of a pokemon in each sphere to useful classification
# Change all but one instance of a Pokémon in each sphere to useful classification
# This cuts down on time calculating the playthrough
found_mons = set()
pokemon = set()
Expand All @@ -277,7 +297,7 @@ def stage_post_fill(cls, multiworld):
found_mons.add(key)

def write_spoiler(self, spoiler_handle: TextIO) -> None:
# Add pokemon locations to the spoiler log if they are not vanilla
# Add Pokémon locations to the spoiler log if they are not vanilla
if self.options.wild_pokemon != RandomizeWildPokemon.option_vanilla:
spoiler_handle.write(f"\n\nPokémon Locations ({self.multiworld.player_name[self.player]}):\n\n")
pokemon_locations: List[PokemonFRLGLocation] = [
Expand Down Expand Up @@ -331,8 +351,8 @@ def create_item_by_id(self, item_id: int):
self.player
)

def create_hm_compatability_dict(self):
hms = frozenset(["Cut", "Fly", "Surf", "Strength", "Flash", "Rock Smash", "Waterfall"])
def _create_hm_compatability_dict(self):
hms = frozenset({"Cut", "Fly", "Surf", "Strength", "Flash", "Rock Smash", "Waterfall"})
for hm in hms:
self.hm_compatability[hm] = list()
for species in frlg_data.species.values():
Expand Down
8 changes: 4 additions & 4 deletions worlds/pokemon_frlg/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"FLAG_GOT_SS_TICKET", # Saved Bill in the Route 25 Sea Cottage
"FLAG_RESCUED_MR_FUJI",
"FLAG_HIDE_SAFFRON_ROCKETS", # Liberated Silph Co.
"FLAG_SYS_CAN_LINK_WITH_RS", # Restored Pokemon Network Machine
"FLAG_SYS_CAN_LINK_WITH_RS", # Restored Pokémon Network Machine
"FLAG_RESCUED_LOSTELLE",
"FLAG_SEVII_DETOUR_FINISHED", # Gave Meteorite to Lostelle's Dad
"FLAG_HIDE_RUIN_VALLEY_SCIENTIST", # Helped Lorelei in Icefall Cave
Expand Down Expand Up @@ -214,7 +214,7 @@ async def game_watcher(self, ctx: "BizHawkClientContext") -> None:

read_result = await bizhawk.guarded_read(
ctx.bizhawk_ctx,
[(sb2_address + 0x028, 0x34, "System Bus")], # Caught Pokemon
[(sb2_address + 0x028, 0x34, "System Bus")], # Caught Pokémon
[guards["IN OVERWORLD"], guards["SAVE BLOCK 2"]]
)

Expand Down Expand Up @@ -248,7 +248,7 @@ async def game_watcher(self, ctx: "BizHawkClientContext") -> None:
if flag_id in EVENT_FLAG_MAP:
local_set_events[EVENT_FLAG_MAP[flag_id]] = True

# Get caught pokemon count
# Get caught Pokémon count
for byte_i, byte in enumerate(pokemon_caught_bytes):
for i in range(8):
if byte & (1 << i) != 0:
Expand Down Expand Up @@ -287,7 +287,7 @@ async def game_watcher(self, ctx: "BizHawkClientContext") -> None:
}])
self.local_set_events = local_set_events

# Send caught pokemon amount
# Send caught Pokémon amount
if caught_pokemon != self.caught_pokemon and ctx.slot is not None:
await ctx.send_msgs([{
"cmd": "Set",
Expand Down
Loading

0 comments on commit 5e611a1

Please sign in to comment.