Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pokemon Crystal: Implement new game #3494

Open
wants to merge 185 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
185 commits
Select commit Hold shift + click to select a range
3b4f662
Pokecrystal - dumping unfiltered data
AliceMousie Oct 30, 2023
44b8719
Pokemon Crystal: Implement generation and output
AliceMousie Nov 6, 2023
1acb43e
Merge remote-tracking branch 'upstream/main' into pokecrystal
AliceMousie Nov 6, 2023
600b786
Pokemon Crystal: Add untracked files
AliceMousie Nov 6, 2023
d5eb22c
Pokemon Crystal: Working client
AliceMousie Nov 7, 2023
f379b84
Pokemon Crystal: Fix blind trainers and start with four moves
AliceMousie Nov 8, 2023
05c784a
Pokemon Crystal: Logic and apworld compatibility
AliceMousie Nov 8, 2023
a3b7dc5
Pokemon Crystal: Client sets goal flag for Red
AliceMousie Nov 8, 2023
d56fc1d
Pokemon Crystal: Many logic fixes
AliceMousie Nov 10, 2023
34868f0
Pokemon Crystal: More logic tweaks and patches
AliceMousie Nov 10, 2023
25f81f6
Pokemon Crystal: Generation and logic fixes
AliceMousie Nov 10, 2023
d943c3d
Pokemon Crystal: Added many options and bugfixes
AliceMousie Nov 12, 2023
160576b
Merge remote-tracking branch 'upstream/main' into pokecrystal
AliceMousie Nov 12, 2023
23f70b4
Pokemon Crystal: Move to options_dataclass, Fix Tyrogue bugs, Fix RB …
AliceMousie Nov 12, 2023
2dafbac
Pokemon Crystal: Tidy-up and fix for HMs in learnsets
AliceMousie Nov 13, 2023
4d6184d
Pokemon Crystal - Bugfixes, start_inventory support
AliceMousie Nov 24, 2023
8a0d64e
Merge remote-tracking branch 'upstream/main' into pokecrystal
AliceMousie Nov 24, 2023
97185f2
Pokemon Crystal: Fixed Silver Leaf classification
AliceMousie Nov 28, 2023
0a14a70
Merge remote-tracking branch 'upstream/main' into pokecrystal
AliceMousie Nov 28, 2023
48c5658
Pokemon Crystal: Fix Lake of Rage check
AliceMousie Dec 3, 2023
081043a
Pokemon Crystal: Remove Bill's Grandpa checks from pool
AliceMousie Dec 3, 2023
b914a0f
Pokemon Crystal: Remove Struggle and Beat Up from move pool
AliceMousie Dec 9, 2023
d0134da
Pokemon Crystal: Renamed Vermilion HP Up check and fixed Lost Item ch…
AliceMousie Dec 17, 2023
42f5bf2
Pokemon Crystal: Fix region connection issues
AliceMousie Jan 5, 2024
4db3ef4
Pokemon Crystal: Grass wild slots match
AliceMousie Jan 5, 2024
f0640bd
Pokemon Crystal: Underground Path logic
AliceMousie Jan 5, 2024
6c6dd49
Pokemon Crystal: Normalize Encounter Rates option
AliceMousie Jan 5, 2024
7e01b37
Pokemon Crystal: Normalized growth rates in basepatch
AliceMousie Jan 5, 2024
399eedf
Pokemon Crystal: Randomize Togepi
AliceMousie Jan 5, 2024
740fb36
Pokemon Crystal: Change dragon fang item to itemball
AliceMousie Jan 5, 2024
71cf0d9
Pokemon Crystal: Fix order of Marsh and Soul badges on trainer card
AliceMousie Jan 7, 2024
29619a7
Merge remote-tracking branch 'upstream/main' into pokecrystal
AliceMousie Jan 7, 2024
4ff12e6
Pokemon Crystal: Various logic fixes
AliceMousie Jan 19, 2024
c7f8980
Pokemon Crystal: Fix Pharmacy check after Amphy is healed
AliceMousie Jan 19, 2024
47345f4
Pokemon Crystal: Add region connections from ship to ports
AliceMousie Jan 19, 2024
2fb26e1
Pokemon Crystal: Rename locations
AliceMousie Jan 19, 2024
b5cf79b
Pokemon Crystal: Fix normalize encounter rate bug
AliceMousie Jan 21, 2024
cd10616
Pokemon Crystal: Make utils, remove Unown from randoms
AliceMousie Jan 22, 2024
2b451c3
Pokemon Crystal: Add missing hidden items to regions
AliceMousie Jan 22, 2024
0021672
Pokemon Crystal: Auto rocket takeover and instant text turbo
AliceMousie Jan 23, 2024
4a8b5e4
Pokemon Crystal: Fix non-instant speeds
AliceMousie Jan 23, 2024
2dab232
Pokemon Crystal: Reusable TMs option
AliceMousie Jan 23, 2024
e72fe27
Pokemon Crystal: Basepatch fixes, catch options
AliceMousie Jan 25, 2024
07898c7
Pokemon Crystal: Remove E4 requirement from Red battle
AliceMousie Jan 25, 2024
4422a3a
Pokemon Crystal: Allow fighting Rocket Exec before Fake Director
AliceMousie Jan 25, 2024
42e66df
Pokemon Crystal: Logic fixes
AliceMousie Jan 27, 2024
cc4611a
Pokemon Crystal: Tracker Compatibility
AliceMousie Jan 27, 2024
a64fdda
Pokemon Crystal: Turbo on waitbutton events
AliceMousie Jan 28, 2024
4ba8a7b
Pokemon Crystal: Pokegear randomization
AliceMousie Jan 28, 2024
d66784a
Pokemon Crystal: Fix Hive Badge address
AliceMousie Jan 28, 2024
e34f78d
Pokemon Crystal: Fix generation for Pokegear rando
AliceMousie Jan 28, 2024
278e856
Pokemon Crystal: Trainersanity WIP
AliceMousie Feb 1, 2024
1a6def5
Pokemon Crystal: Fix Mt Mortar 2F item name
AliceMousie Feb 1, 2024
898001b
Pokemon Crystal: Misc fixes
AliceMousie Feb 4, 2024
d103080
Pokemon Crystal: Basepatch fixes
AliceMousie Feb 12, 2024
e812db1
Pokemon Crystal: 7th Badge and Aide check fixes (again)
AliceMousie Feb 18, 2024
3eb15d4
Pokemon Crystal: Basepatch
AliceMousie Feb 18, 2024
97a956c
Pokecrystal: Merge main into unstable
AliceMousie Feb 19, 2024
fa24b05
Pokecrystal: Rebuild Basepatch
AliceMousie Feb 19, 2024
8b37f5f
So many changes
AliceMousie Feb 25, 2024
d841922
Pokemon Crystal: Fix Radio Tower after-clear checks logic
AliceMousie Feb 25, 2024
363a065
Merge branch 'pokecrystal' into pokecrystal-unstable
AliceMousie Feb 25, 2024
4029622
Pokemon Crystal: Add phone trap, badge number text
AliceMousie Feb 28, 2024
204e8d5
Pokemon Crystal: Randomize wild fish
AliceMousie Apr 12, 2024
e69f129
Merge remote-tracking branch 'upstream/main' into pokecrystal-unstable
AliceMousie Apr 12, 2024
495b82d
Pokemon Crystal - Fix dupe events and per_slot_randoms
AliceMousie Apr 12, 2024
304c4cc
Pokemon Crystal: Add Johto Only mode
AliceMousie May 8, 2024
cc403fe
Pokemon Crystal: Fix Johto only validation
AliceMousie May 9, 2024
9d162ac
Pokemon Crystal: Remove early game event rules
AliceMousie May 9, 2024
9c08d3e
Pokemon Crystal: Add random base stats, types, palettes
AliceMousie May 14, 2024
8bfcb98
Pokemon Crystal: Add rules for HM requirements
AliceMousie May 14, 2024
348f780
Pokemon Crystal: TM and HM compatibility options
AliceMousie May 14, 2024
fb5f842
Pokemon Crystal: Option for vanilla or shuffled badges
AliceMousie May 15, 2024
677b0c3
Pokemon Crystal: Status traps
AliceMousie May 15, 2024
e8e693f
Pokemon Crystal: Include missing trainersanity locations
AliceMousie May 15, 2024
94cdca5
Pokemon Crystal: Trainersanity and Ruins of Alph logic
AliceMousie May 16, 2024
846a417
Pokemon Crystal: Add mischief, phone traps
AliceMousie May 18, 2024
6c653b5
Pokemon Crystal: Add mischief, phone traps
AliceMousie May 18, 2024
307999d
Pokemon Crystal: Traps bugfixes
AliceMousie May 18, 2024
abd8f86
Merge remote-tracking branch 'upstream/main' into pokecrystal-unstable
AliceMousie May 18, 2024
3295118
Pokemon Crystal: Client Fixes and Option changed
AliceMousie May 18, 2024
66126d1
Pokemon Crystal: Safely handle missing phone slot data
AliceMousie May 18, 2024
6203e5e
Pokemon Crystal: Fix infinite phone traps, move data to ROM
AliceMousie May 18, 2024
94d7326
Pokemon Crystal: Fix graphical issues with HM dialog
AliceMousie May 18, 2024
dc93e98
Pokemon Crystal: Randomize TM moves
AliceMousie May 18, 2024
8788b0c
Pokemon Crystal: Randomize headbutt pokemon
AliceMousie May 18, 2024
9672886
Pokemon Crystal: Fix prices on stones and evo items
AliceMousie May 19, 2024
5f7587f
Pokemon Crystal: Fix mischief
AliceMousie May 19, 2024
808e364
Pokemon Crystal: Misc fixes from testing
AliceMousie May 20, 2024
5abecfe
Pokemon Crystal: Brighten dark type palette
AliceMousie May 20, 2024
63fbe2c
Pokemon Crystal: Fixes to Dragon's Den locations and rules
AliceMousie May 20, 2024
2e7f8dc
Pokemon Crystal: More fixes
AliceMousie May 20, 2024
58372df
Pokemon Crystal: Changed TM/HM options to NamedRange
AliceMousie May 20, 2024
ea5a514
Pokemon Crystal: Exclude move 00 from TM move randomization
AliceMousie May 21, 2024
3ba70ea
Pokemon Crystal: Fix Surf Kanto badge rule
AliceMousie May 21, 2024
eaa8a64
Pokemon Crystal: Fix Dragon's Den crash
AliceMousie May 21, 2024
d1006bc
Pokemon Crystal: Add tracker tag to items
AliceMousie May 21, 2024
ae65744
Pokemon Crystal: Fix Pokegear and EXPN card not having Pokegear tag
AliceMousie May 21, 2024
35d5941
Pokemon Crystal: Logic fixes
AliceMousie May 21, 2024
7c04709
Pokemon Crystal: Use ROM checksum for rom version
AliceMousie May 21, 2024
5a63b63
Pokemon Crystal: Pass tracker tag
AliceMousie May 22, 2024
b1d31d6
Pokemon Crystal: Update Basepatch to try and prevent status trap crash
AliceMousie May 22, 2024
c296808
Pokemon Crystal: Fixed and tested item recieve crashes
AliceMousie May 23, 2024
c905885
Pokemon Crystal: Fix Route 34 regions
AliceMousie May 24, 2024
193aec6
Pokemon Crystal: Fix items data for TM08
AliceMousie May 28, 2024
9291ab6
Pokemon Crystal: Fix trainersanity checks on Route 17
AliceMousie May 29, 2024
dc931ce
Pokemon Crystal: Change client incompatibility warning
AliceMousie May 29, 2024
745c60c
Pokemon Crystal: Basepatch changes, added trainersanity alerts option
AliceMousie May 30, 2024
44ff22e
Pokemon Crystal: Fix headbutt randomization
AliceMousie May 31, 2024
256c74c
Pokemon Crystal: Fix off-by-one error in TM/HM compatibility
AliceMousie May 31, 2024
b205270
Pokemon Crystal: Fix Union Cave trainers logic
AliceMousie May 21, 2024
07372b4
Pokemon Crystal: Send Bounce packets on map change for tracker
AliceMousie Jun 1, 2024
502ba44
Pokemon Crystal: Fix getting stuck in wall reboarding Fast Ship
AliceMousie Jun 1, 2024
f700ad1
Pokemon Crystal: Blacklist struggle from random TMs
AliceMousie Jun 1, 2024
e9ec34e
Pokemon Crystal: Exclude Olivine Port from Johto-Only
AliceMousie Jun 1, 2024
da526a6
Pokemon Crystal: Mischief Change
AliceMousie Jun 2, 2024
2a02fcb
Pokemon Crystal: Improve Mischief
AliceMousie Jun 3, 2024
6184bdf
Pokemon Crystal: Display names of AP Items in game
AliceMousie Jun 4, 2024
5d6d3b5
Merge remote-tracking branch 'upstream/main' into pokecrystal
AliceMousie Jun 4, 2024
6a7c261
Pokemon Crystal: Change preset trainer movesets if learnsets are rand…
AliceMousie Jun 4, 2024
2be066e
Pokemon Crystal: Add Item Groups
AliceMousie Jun 4, 2024
774277c
Pokemon Crystal: Fly between regions
AliceMousie Jun 4, 2024
212d2bf
Pokemon Crystal: Remove non-trainersanity trainers from Fast Ship
AliceMousie Jun 4, 2024
0cde555
Pokemon Crystal: Add free fly location
AliceMousie Jun 4, 2024
26f8ee1
Pokemon Crystal: Add no free fly to slot data
AliceMousie Jun 4, 2024
b72d20a
Pokemon Crystal: Add music randomization
AliceMousie Jun 5, 2024
771c422
Pokemon Crystal: Fix rules for free fly
AliceMousie Jun 5, 2024
d6f9739
Pokemon Crystal: Fix free fly regions
AliceMousie Jun 5, 2024
bce4e03
Pokemon Crystal: Randomize Berry Trees
AliceMousie Jun 5, 2024
10630c2
Pokemon Crystal: Remove unused events from regions.json
AliceMousie Jun 5, 2024
5dd4d16
Pokemon Crystal: Fix rules mishap
AliceMousie Jun 5, 2024
521f60a
Pokemon Crystal: Access to Silver Cave by talking to guard
AliceMousie Jun 5, 2024
dfda151
Pokemon Crystal: Logic tweak
AliceMousie Jun 5, 2024
f3174f7
Pokemon Crystal: Differentiate item received sound for traps and key …
AliceMousie Jun 6, 2024
e7a9ded
Pokemon Crystal: Fix location name
AliceMousie Jun 6, 2024
dfb705c
Pokemon Crystal: Spring cleaning
AliceMousie Jun 6, 2024
b62766c
Pokemon Crystal: Add Johto only red goal, Johto only badges > 8
AliceMousie Jun 6, 2024
c7f21ab
Pokemon Crystal: Switch to APProcedurePatch
AliceMousie Jun 6, 2024
3c80094
Pokemon Crystal: Misc. fixes
AliceMousie Jun 7, 2024
ddcb0d4
Pokemon Crystal: Add placeholder docs
AliceMousie Jun 7, 2024
24f798e
Pokemon Crystal: Make evolutions and trainer party data into classes
AliceMousie Jun 7, 2024
fc86dc7
Pokemon Crystal: Fix trade evolution items not working
AliceMousie Jun 7, 2024
115ae57
Pokemon Crystal: Add some tests
AliceMousie Jun 7, 2024
001ab4b
Pokemon Crystal: Move test helper out of test file
AliceMousie Jun 7, 2024
4430351
Pokemon Crystal: Change helper function name
AliceMousie Jun 7, 2024
487be35
Pokemon Crystal: Add Map Card fly location
AliceMousie Jun 7, 2024
4314ba5
Pokemon Crystal: basepatch changes
AliceMousie Jun 7, 2024
eb09bee
Pokemon Crystal: Add Escape Rope and Water Stone purchase tracking
AliceMousie Jun 7, 2024
a9e4f35
Pokemon Crystal: More refactoring
AliceMousie Jun 8, 2024
f8062ab
Pokemon Crystal: Basepatch fixes
AliceMousie Jun 8, 2024
30be979
Pokemon Crystal: Fix apworld on 0.4.6 installs
AliceMousie Jun 8, 2024
c5f3056
Pokemon Crystal: Update docs, tests
AliceMousie Jun 8, 2024
e403b7e
Pokemon Crystal: Fix alignment issue with empty trainer moveslots
AliceMousie Jun 8, 2024
4a94967
Merge remote-tracking branch 'upstream/main' into pokecrystal
AliceMousie Jun 8, 2024
143fea5
Pokemon Crystal: Cleanup some unused functions
AliceMousie Jun 8, 2024
b31fedb
Pokemon Crystal: Changes to option docstrings
AliceMousie Jun 8, 2024
6896f90
Pokemon Crystal: Add to CODEOWNERS and README
AliceMousie Jun 8, 2024
2f397f2
Pokemon Crystal: Remove incorrect connection
AliceMousie Jun 8, 2024
a9b4d25
Pokemon Crystal: Change to trap options docstrings
AliceMousie Jun 8, 2024
885f6e1
Pokemon Crystal: Add get_filler_item_name function
AliceMousie Jun 8, 2024
adc55e7
Pokemon Crystal: Fix CODEOWNERS order
AliceMousie Jun 8, 2024
0f96773
Pokemon Crystal: Removed item sphere code from remote phone traps, dr…
AliceMousie Jun 8, 2024
dd1a9c5
Pokemon Crystal: Check server state for phone trap hints
AliceMousie Jun 8, 2024
5272270
Pokemon Crystal: Remove id offset, remove commented out code
AliceMousie Jun 9, 2024
9425cac
Pokemon Crystal: Add missing rule to Fuchsia berry tree
AliceMousie Jun 9, 2024
6aca55f
Pokemon Crystal: Add early fly option
AliceMousie Jun 9, 2024
d57d2b2
Merge branch 'pokecrystal_dev' into pokecrystal
AliceMousie Jun 9, 2024
38240dc
Pokemon Crystal: Change dept. store TM08 to unlock when received
AliceMousie Jun 11, 2024
5908e28
Pokemon Crystal: Logic fix
AliceMousie Jun 11, 2024
c4ea26d
Pokemon Crystal: Improve music rando
AliceMousie Jun 13, 2024
1629f8e
Pokemon Crystal: Review changes
AliceMousie Jun 13, 2024
c905def
Pokemon Crystal: Merge in changes
AliceMousie Jun 13, 2024
1352fed
Pokemon Crystal: Remove data_version, correct client version
AliceMousie Jun 13, 2024
c8f25d5
Pokemon Crystal: Fix trainersanity item sound always playing
AliceMousie Jun 14, 2024
98374de
Merge remote-tracking branch 'upstream/main' into pokecrystal
AliceMousie Jun 14, 2024
05700ad
Pokemon Crystal: More review changes
AliceMousie Jun 14, 2024
4019f52
Pokemon Crystal: Review changes, V1.1 support
AliceMousie Jul 15, 2024
6777a01
Pokemon Crystal: Loop phone traps after 16
AliceMousie Jul 15, 2024
b86e70a
Pokemon Crystal: Basepatch fixes
AliceMousie Jul 16, 2024
6e16950
Pokemon Crystal: Small fixes
AliceMousie Jul 18, 2024
9ca4779
Merge remote-tracking branch 'upstream/main' into pokecrystal
AliceMousie Jul 18, 2024
e2fddb8
Pokemon Crystal: Randomize Kenya
AliceMousie Jul 18, 2024
0a07c18
Pokemon Crystal: Use 8 bytes for phone trap location IDs
AliceMousie Jul 19, 2024
a599fce
Pokemon Crystal: Fix non-local locations being added to phone traps
AliceMousie Jul 20, 2024
78bbdc6
Pokemon Crystal: Refactor rules, fix moves issue
AliceMousie Jul 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ Currently, the following games are supported:
* Aquaria
* Yu-Gi-Oh! Ultimate Masters: World Championship Tournament 2006
* A Hat in Time
* Pokémon Crystal

For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/).
Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled
Expand Down
3 changes: 3 additions & 0 deletions docs/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@
# Overcooked! 2
/worlds/overcooked2/ @toasterparty

# Pokemon Crystal
AliceMousie marked this conversation as resolved.
Show resolved Hide resolved
/worlds/pokemon_crystal/ @AliceMousie

# Pokemon Emerald
/worlds/pokemon_emerald/ @Zunawe

Expand Down
323 changes: 323 additions & 0 deletions worlds/pokemon_crystal/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
import copy
import logging
import pkgutil
from typing import List, Union, ClassVar, Dict, Any, Tuple

import settings
from BaseClasses import Tutorial, ItemClassification
from Fill import fill_restrictive
from worlds.AutoWorld import World, WebWorld
from .client import PokemonCrystalClient
from .data import PokemonData, TrainerData, MiscData, TMHMData, data as crystal_data, \
WildData, StaticPokemon, MusicData
from .items import PokemonCrystalItem, create_item_label_to_code_map, get_item_classification, \
ITEM_GROUPS, item_const_name_to_id, item_const_name_to_label
from .locations import create_locations, PokemonCrystalLocation, create_location_label_to_id_map
from .misc import misc_activities, get_misc_spoiler_log
from .moves import randomize_tms
from .music import randomize_music
from .options import PokemonCrystalOptions, JohtoOnly, RandomizeBadges, Goal, HMBadgeRequirements
from .phone import generate_phone_traps
from .phone_data import PhoneScript
from .pokemon import randomize_pokemon, randomize_starters
from .regions import create_regions, setup_free_fly
from .rom import generate_output, PokemonCrystalProcedurePatch
from .rules import set_rules
from .trainers import randomize_trainers, vanilla_trainer_movesets
from .utils import get_random_filler_item, get_free_fly_location
from .wild import randomize_wild_pokemon, randomize_static_pokemon


class PokemonCrystalSettings(settings.Group):
class RomFile(settings.UserFilePath):
description = "Pokemon Crystal (UE) (V1.0 or V1.1) ROM File"
copy_to = "Pokemon - Crystal Version (UE) [C][!].gbc"
md5s = ["9f2922b235a5eeb78d65594e82ef5dde", "301899b8087289a6436b0a241fbbb474"]

rom_file: RomFile = RomFile(RomFile.copy_to)


class PokemonCrystalWebWorld(WebWorld):
tutorials = [Tutorial(
"Multiworld Setup Guide",
"A guide to playing Pokemon Crystal with Archipelago.",
"English",
"setup_en.md",
"setup/en",
["AliceMousie"]
)]


class PokemonCrystalWorld(World):
"""Pokémon Crystal is the culmination of the Generation I and II Pokémon games.
Explore the Johto and Kanto regions, become the Pokémon League Champion, and
defeat the elusive Red at the peak of Mt. Silver!"""
game = "Pokemon Crystal"

topology_present = True
web = PokemonCrystalWebWorld()

settings_key = "pokemon_crystal_settings"
settings: ClassVar[PokemonCrystalSettings]

options_dataclass = PokemonCrystalOptions
options: PokemonCrystalOptions

required_client_version = (0, 5, 0)

item_name_to_id = create_item_label_to_code_map()
location_name_to_id = create_location_label_to_id_map()
item_name_groups = ITEM_GROUPS # item_groups

free_fly_location: int
map_card_fly_location: int
generated_pokemon: Dict[str, PokemonData]
generated_starters: Tuple[List[str], List[str], List[str]]
generated_starter_helditems: Tuple[str, str, str]
generated_trainers: Dict[str, TrainerData]
generated_palettes: Dict[str, List[int]]
generated_phone_traps: List[PhoneScript]
generated_phone_indices: List[int]
generated_misc: MiscData
generated_tms: Dict[str, TMHMData]
generated_wild: WildData
generated_music: MusicData
generated_wooper: str
generated_static: Dict[str, StaticPokemon]

def generate_early(self) -> None:
if self.options.early_fly:
self.multiworld.local_early_items[self.player]["HM02 Fly"] = 1
if (self.options.hm_badge_requirements.value != HMBadgeRequirements.option_no_badges
and self.options.randomize_badges == RandomizeBadges.option_completely_random):
self.multiworld.local_early_items[self.player]["Storm Badge"] = 1

if self.options.johto_only:
if self.options.goal == Goal.option_red and self.options.johto_only == JohtoOnly.option_on:
self.options.goal.value = Goal.option_elite_four
logging.warning(
"Pokemon Crystal: Red goal is incompatible with Johto Only "
"without Silver Cave. Changing goal to Elite Four for player %s.",
self.multiworld.get_player_name(self.player))
AliceMousie marked this conversation as resolved.
Show resolved Hide resolved
if self.options.randomize_badges != RandomizeBadges.option_completely_random:
if self.options.red_badges.value > 8:
self.options.red_badges.value = 8
logging.warning(
"Pokemon Crystal: Red Badges >8 incompatible with Johto Only "
"if badges are not completely random. Changing Red Badges to 8 for player %s.",
self.multiworld.get_player_name(self.player))
if self.options.elite_four_badges.value > 8:
self.options.elite_four_badges.value = 8
logging.warning(
"Pokemon Crystal: Elite Four Badges >8 incompatible with Johto Only "
"if badges are not completely random. Changing Elite Four Badges to 8 for player %s.",
self.multiworld.get_player_name(self.player))

def create_regions(self) -> None:
regions = create_regions(self)
create_locations(self, regions)
self.multiworld.regions.extend(regions.values())
if self.options.free_fly_location:
get_free_fly_location(self)
setup_free_fly(self)

def create_items(self) -> None:
item_locations = [
location
for location in self.multiworld.get_locations(self.player)
if location.address is not None
]

if self.options.randomize_badges.value == RandomizeBadges.option_shuffle:
item_locations = [location for location in item_locations if "Badge" not in location.tags]

total_badges = max(self.options.elite_four_badges.value, self.options.red_badges.value)
add_badges = []
# Extra badges to add to the pool in johto only
if self.options.johto_only and total_badges > 8:
AliceMousie marked this conversation as resolved.
Show resolved Hide resolved
kanto_badges = [item_id for item_id, item_data in crystal_data.items.items() if
"KantoBadge" in item_data.tags]
self.random.shuffle(kanto_badges)
add_badges = kanto_badges[:total_badges - 8]

trap_names, trap_weights = zip(
("Phone Trap", self.options.phone_trap_weight.value),
("Sleep Trap", self.options.sleep_trap_weight.value),
("Poison Trap", self.options.poison_trap_weight.value),
("Burn Trap", self.options.burn_trap_weight.value),
("Freeze Trap", self.options.freeze_trap_weight.value),
("Paralysis Trap", self.options.paralysis_trap_weight.value),
)
total_trap_weight = sum(trap_weights)

def get_random_trap():
return self.create_item(self.random.choices(trap_names, trap_weights)[0])

default_itempool = []

for location in item_locations:
item_code = location.default_item_code
if item_code > 0 and get_item_classification(item_code) != ItemClassification.filler:
# If TMs are randomized, TM items without move names are added to the pool
if item_code in crystal_data.tm_replace_map and self.options.randomize_tm_moves:
default_itempool += [self.create_item_by_code(item_code + 256)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default_itempool.append(item)
is faster and (in my opinion) more readable than
default_itempool += [item]

Same for other instances below.

else:
default_itempool += [self.create_item_by_code(item_code)]
elif len(add_badges):
default_itempool += [self.create_item_by_code(add_badges.pop())]
elif self.random.randint(0, 100) < total_trap_weight:
default_itempool += [get_random_trap()]
elif item_code == 0: # item is NO_ITEM, trainersanity checks
default_itempool += [self.create_item_by_const_name(get_random_filler_item(self.random))]
else:
default_itempool += [self.create_item_by_code(item_code)]

self.multiworld.itempool += default_itempool

def set_rules(self) -> None:
set_rules(self)

def pre_fill(self) -> None:
if self.options.randomize_badges.value == RandomizeBadges.option_shuffle:
badge_locs = [loc for loc in self.multiworld.get_locations(self.player) if "Badge" in loc.tags]
badge_items = [self.create_item_by_code(loc.default_item_code) for loc in badge_locs]
if self.options.early_fly:
# take one of the 3 early badge locations, set it to storm badge
storm_loc = self.random.choice([loc for loc in badge_locs if "EarlyBadge" in loc.tags])
storm_badge = next(item for item in badge_items if item.name == "Storm Badge")
storm_loc.place_locked_item(storm_badge)
badge_locs.remove(storm_loc)
badge_items.remove(storm_badge)

# 5/8 badge locations in each region do not require a HM to access, so only trying once should be okay.
# I generated 1000 seeds with shuffled badges and none of them broke here, so it's fine probably
self.random.shuffle(badge_locs)
collection_state = self.multiworld.get_all_state(False)
fill_restrictive(self.multiworld, collection_state, badge_locs, badge_items,
single_player_placement=True, lock=True, allow_excluded=True)

def generate_output(self, output_directory: str) -> None:

self.generated_pokemon = copy.deepcopy(crystal_data.pokemon)
self.generated_starters = (["CYNDAQUIL", "QUILAVA", "TYPHLOSION"],
["TOTODILE", "CROCONAW", "FERALIGATR"],
["CHIKORITA", "BAYLEEF", "MEGANIUM"])
self.generated_starter_helditems = ("BERRY", "BERRY", "BERRY")
self.generated_trainers = copy.deepcopy(crystal_data.trainers)
self.generated_misc = copy.deepcopy(crystal_data.misc)
self.generated_tms = copy.deepcopy(crystal_data.tmhm)
self.generated_wild = copy.deepcopy(crystal_data.wild)
self.generated_static = copy.deepcopy(crystal_data.static)
self.generated_music = copy.deepcopy(crystal_data.music)
self.generated_palettes = {}
self.generated_phone_traps = []
self.generated_phone_indices = []
self.generated_wooper = "WOOPER"

randomize_pokemon(self)

if self.options.randomize_starters.value:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm always going to be a fan of checking options explicitly against named values rather than relying on the falsiness of the particular option value, but I think I may be in the minority there. I value the safety and readability, but I know others consider it verbose and less elegant.

Disregard if you like it as it is.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I may have made this comment before; I'll try to remember that my opinion has been shared already and stop flagging it, lol.

Copy link
Member

@NewSoupVi NewSoupVi Aug 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be even less characters: if self.options.randomize_starters

Copy link
Member

@NewSoupVi NewSoupVi Aug 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either way, everything that's been mentioned here is fine as far as core is concerned :)

randomize_starters(self)

if self.options.randomize_tm_moves.value:
randomize_tms(self)

if self.options.randomize_trainer_parties.value:
randomize_trainers(self)
elif self.options.randomize_learnsets.value:
vanilla_trainer_movesets(self)

if self.options.randomize_wilds.value:
randomize_wild_pokemon(self)

if self.options.randomize_static_pokemon.value:
randomize_static_pokemon(self)

if self.options.randomize_music.value:
randomize_music(self)

if self.options.enable_mischief.value:
misc_activities(self)

if self.options.phone_trap_weight.value:
generate_phone_traps(self)

patch = PokemonCrystalProcedurePatch(player=self.player, player_name=self.player_name)
patch.write_file("basepatch.bsdiff4", pkgutil.get_data(__name__, "data/basepatch.bsdiff4"))
patch.write_file("basepatch11.bsdiff4", pkgutil.get_data(__name__, "data/basepatch11.bsdiff4"))
generate_output(self, output_directory, patch)

def fill_slot_data(self) -> Dict[str, Any]:
slot_data = self.options.as_dict(
"goal",
"johto_only",
"elite_four_badges",
"red_badges",
"randomize_badges",
"randomize_hidden_items",
"require_itemfinder",
"trainersanity",
"randomize_pokegear",
"hm_badge_requirements",
"randomize_berry_trees"
)
slot_data["free_fly_location"] = 0
slot_data["map_card_fly_location"] = 0
if self.options.free_fly_location:
slot_data["free_fly_location"] = self.free_fly_location
if self.options.free_fly_location > 1:
slot_data["map_card_fly_location"] = self.map_card_fly_location

return slot_data

def write_spoiler(self, spoiler_handle) -> None:
if self.options.randomize_starters:
spoiler_handle.write(f"\n\nStarter Pokemon ({self.multiworld.player_name[self.player]}):\n\n")
for evo in self.generated_starters:
types_0 = ", ".join(self.generated_pokemon[evo[0]].types)
types_1 = ", ".join(self.generated_pokemon[evo[1]].types)
types_2 = ", ".join(self.generated_pokemon[evo[2]].types)
spoiler_handle.write(f"{evo[0]} ({types_0}) -> {evo[1]} ({types_1}) -> {evo[2]} ({types_2})\n")

if self.options.free_fly_location:
free_fly_locations = {22: "Ecruteak City",
21: "Olivine City",
19: "Cianwood City",
23: "Mahogany Town",
25: "Blackthorn City",
3: "Viridian City",
4: "Pewter City",
5: "Cerulean City",
7: "Vermilion City",
8: "Lavender Town",
10: "Celadon City",
9: "Saffron City",
11: "Fuchsia City"}
spoiler_handle.write(f"\n\nFree Fly Location ({self.multiworld.player_name[self.player]}): "
f"{free_fly_locations[self.free_fly_location]}\n")
if self.options.free_fly_location > 1:
spoiler_handle.write(f"\n\nMap Card Fly Location ({self.multiworld.player_name[self.player]}): "
f"{free_fly_locations[self.map_card_fly_location]}\n")

if self.options.enable_mischief:
spoiler_handle.write(f"\n\nMischief ({self.multiworld.player_name[self.player]}):\n\n")
get_misc_spoiler_log(self, spoiler_handle.write)

def create_item(self, name: str) -> PokemonCrystalItem:
return self.create_item_by_code(self.item_name_to_id[name])

def get_filler_item_name(self) -> str:
item = get_random_filler_item(self.random)
return item_const_name_to_label(item)

def create_item_by_const_name(self, item_const: str) -> PokemonCrystalItem:
item_code = item_const_name_to_id(item_const)
return self.create_item_by_code(item_code)

def create_item_by_code(self, item_code: int) -> PokemonCrystalItem:
return PokemonCrystalItem(
self.item_id_to_name[item_code],
get_item_classification(item_code),
item_code,
self.player
)
Loading