Pokemon Emerald: v2 Update (#2918)

This commit is contained in:
Bryce Wilson
2024-03-14 05:37:10 -06:00
committed by GitHub
parent 3e3965272d
commit fa233b2583
34 changed files with 14212 additions and 3240 deletions

View File

@@ -2,9 +2,9 @@
Option definitions for Pokemon Emerald
"""
from dataclasses import dataclass
from typing import Dict, Type
from Options import Choice, DefaultOnToggle, Option, OptionSet, Range, Toggle, FreeText, PerGameCommonOptions
from Options import (Choice, DeathLink, DefaultOnToggle, TextChoice, OptionSet, NamedRange, Range, Toggle, FreeText,
PerGameCommonOptions)
from .data import data
@@ -16,12 +16,14 @@ class Goal(Choice):
Champion: Become the champion and enter the hall of fame
Steven: Defeat Steven in Meteor Falls
Norman: Defeat Norman in Petalburg Gym
Legendary Hunt: Defeat or catch legendary pokemon (or whatever was randomized into their encounters)
"""
display_name = "Goal"
default = 0
option_champion = 0
option_steven = 1
option_norman = 2
option_legendary_hunt = 3
class RandomizeBadges(Choice):
@@ -69,6 +71,13 @@ class RandomizeBikes(Toggle):
display_name = "Randomize Bikes"
class RandomizeEventTickets(Toggle):
"""
Adds the event tickets to the pool, which let you access legendaries by sailing from Lilycove
"""
display_name = "Randomize Event Tickets"
class RandomizeRods(Toggle):
"""
Adds fishing rods to the pool
@@ -97,13 +106,40 @@ class RandomizeNpcGifts(Toggle):
display_name = "Randomize NPC Gifts"
class RandomizeBerryTrees(Toggle):
"""
Adds berry trees to the pool. Empty soil patches are converted to locations and contribute Sitrus Berries to the pool.
"""
display_name = "Randomize Berry Trees"
class Dexsanity(Toggle):
"""
Adding a "caught" pokedex entry gives you an item (catching, evolving, trading, etc.).
Defeating gym leaders provides dex info, allowing you to see where on the map you can catch species you need.
Each pokedex entry adds a Poke Ball, Great Ball, or Ultra Ball to the pool.
"""
display_name = "Dexsanity"
class Trainersanity(Toggle):
"""
Defeating a trainer for the first time gives you an item. Trainers are no longer missable.
Trainers no longer give you money for winning. Each trainer adds a valuable item (nugget, stardust, etc.) to the pool.
"""
display_name = "Trainersanity"
class ItemPoolType(Choice):
"""
Determines which non-progression items get put into the item pool
Shuffled: Item pool consists of shuffled vanilla items
Diverse Balanced: Item pool consists of random items approximately proportioned
according to what they're replacing (i.e. more pokeballs, fewer X items, etc...)
according to what they're replacing (i.e. more pokeballs, fewer X items, etc.)
Diverse: Item pool consists of uniformly random (non-unique) items
"""
display_name = "Item Pool Type"
@@ -120,18 +156,16 @@ class HiddenItemsRequireItemfinder(DefaultOnToggle):
display_name = "Require Itemfinder"
class DarkCavesRequireFlash(DefaultOnToggle):
class DarkCavesRequireFlash(Choice):
"""
The lower floors of Granite Cave and Victory Road logically require use of HM05 Flash
Determines whether HM05 Flash is logically required to navigate a dark cave
"""
display_name = "Require Flash"
class EnableFerry(Toggle):
"""
The ferry between Slateport, Lilycove, and the Battle Frontier can be used if you have the S.S. Ticket
"""
display_name = "Enable Ferry"
default = 3
option_neither = 0
option_only_granite_cave = 1
option_only_victory_road = 2
option_both = 3
class EliteFourRequirement(Choice):
@@ -180,6 +214,61 @@ class NormanCount(Range):
default = 4
class LegendaryHuntCatch(Toggle):
"""
Sets whether legendaries need to be caught to satisfy the Legendary Hunt win condition. Defeated legendaries can be respawned by defeating the Elite 4.
"""
display_name = "Legendary Hunt Requires Catching"
class LegendaryHuntCount(Range):
"""
Sets the number of legendaries that must be caught/defeated for the Legendary Hunt goal
"""
display_name = "Legendary Hunt Count"
range_start = 1
range_end = 12
default = 3
class AllowedLegendaryHuntEncounters(OptionSet):
"""
Sets which legendary encounters can contribute to the Legendary Hunt goal.
Latios will always be the roamer. Latias will always be at Southern Island.
Possible values are:
"Groudon"
"Kyogre"
"Rayquaza"
"Latios"
"Latias"
"Regirock"
"Registeel"
"Regice"
"Ho-oh"
"Lugia"
"Deoxys"
"Mew"
"""
display_name = "Allowed Legendary Hunt Encounters"
valid_keys = frozenset([
"Groudon",
"Kyogre",
"Rayquaza",
"Latios",
"Latias",
"Regirock",
"Registeel",
"Regice",
"Ho-oh",
"Lugia",
"Deoxys",
"Mew",
])
default = valid_keys.copy()
class RandomizeWildPokemon(Choice):
"""
Randomizes wild pokemon encounters (grass, caves, water, fishing)
@@ -199,11 +288,16 @@ class RandomizeWildPokemon(Choice):
option_completely_random = 4
class AllowWildLegendaries(DefaultOnToggle):
class WildEncounterBlacklist(OptionSet):
"""
Wild encounters can be replaced by legendaries. Only applied if Randomize Wild Pokemon is not Vanilla.
Prevents listed species from appearing in the wild when wild encounters are randomized.
May be overridden if enforcing other restrictions in combination with this blacklist is impossible.
Use "_Legendaries" as a shortcut for legendary pokemon.
"""
display_name = "Allow Wild Legendaries"
display_name = "Wild Encounter Blacklist"
valid_keys = frozenset(species.label for species in data.species.values()) | {"_Legendaries"}
class RandomizeStarters(Choice):
@@ -225,11 +319,16 @@ class RandomizeStarters(Choice):
option_completely_random = 4
class AllowStarterLegendaries(DefaultOnToggle):
class StarterBlacklist(OptionSet):
"""
Starters can be replaced by legendaries. Only applied if Randomize Starters is not Vanilla.
Prevents listed species from appearing as starters when starters are randomized.
May be overridden if enforcing other restrictions in combination with this blacklist is impossible.
Use "_Legendaries" as a shortcut for legendary pokemon.
"""
display_name = "Allow Starter Legendaries"
display_name = "Starter Blacklist"
valid_keys = frozenset(species.label for species in data.species.values()) | {"_Legendaries"}
class RandomizeTrainerParties(Choice):
@@ -251,25 +350,61 @@ class RandomizeTrainerParties(Choice):
option_completely_random = 4
class AllowTrainerLegendaries(DefaultOnToggle):
class TrainerPartyBlacklist(OptionSet):
"""
Enemy trainer pokemon can be replaced by legendaries. Only applied if Randomize Trainer Parties is not Vanilla.
Prevents listed species from appearing in opponent trainers' parties if opponent parties are randomized.
May be overridden if enforcing other restrictions in combination with this blacklist is impossible.
Use "_Legendaries" as a shortcut for legendary pokemon.
"""
display_name = "Allow Trainer Legendaries"
display_name = "Trainer Party Blacklist"
valid_keys = frozenset(species.label for species in data.species.values()) | {"_Legendaries"}
class RandomizeStaticEncounters(Choice):
class ForceFullyEvolved(Range):
"""
Randomizes static encounters (Rayquaza, hidden Kekleons, fake Voltorb pokeballs, etc...)
When an opponent uses a pokemon of the specified level or higher, restricts the species to only fully evolved pokemon.
"""
display_name = "Force Fully Evolved"
range_start = 1
range_end = 100
default = 100
Vanilla: Static encounters are unchanged
Shuffle: Static encounters are shuffled between each other
Match Base Stats: Static encounters are replaced with species with approximately the same bst
Match Type: Static encounters are replaced with species that share a type with the original
class RandomizeLegendaryEncounters(Choice):
"""
Randomizes legendary encounters (Rayquaza, Regice, Latias, etc.). The roamer will always be Latios during legendary hunts.
Vanilla: Legendary encounters are unchanged
Shuffle: Legendary encounters are shuffled between each other
Match Base Stats: Legendary encounters are replaced with species with approximately the same bst
Match Type: Legendary encounters are replaced with species that share a type with the original
Match Base Stats and Type: Apply both Match Base Stats and Match Type
Completely Random: There are no restrictions
"""
display_name = "Randomize Static Encounters"
display_name = "Randomize Legendary Encounters"
default = 0
option_vanilla = 0
option_shuffle = 1
option_match_base_stats = 2
option_match_type = 3
option_match_base_stats_and_type = 4
option_completely_random = 5
class RandomizeMiscPokemon(Choice):
"""
Randomizes non-legendary static encounters. May grow to include other pokemon like trades or gifts.
Vanilla: Species are unchanged
Shuffle: Species are shuffled between each other
Match Base Stats: Species are replaced with species with approximately the same bst
Match Type: Species are replaced with species that share a type with the original
Match Base Stats and Type: Apply both Match Base Stats and Match Type
Completely Random: There are no restrictions
"""
display_name = "Randomize Misc Pokemon"
default = 0
option_vanilla = 0
option_shuffle = 1
@@ -363,48 +498,52 @@ class MoveNormalTypeBias(Range):
default = 0
class HmCompatibility(Choice):
class MoveBlacklist(OptionSet):
"""
Modifies the compatibility of HMs
A list of moves which should be excluded from learnsets, TMs, and move tutors.
"""
display_name = "Move Blacklist"
valid_keys = frozenset(data.move_labels.keys())
Vanilla: Compatibility is unchanged
Fully Compatible: Every species can learn any HM
Completely Random: Compatibility is 50/50 for every HM (does not remain consistent across evolution)
class HmCompatibility(NamedRange):
"""
Sets the percent chance that a given HM is compatible with a species
"""
display_name = "HM Compatibility"
default = 1
option_vanilla = 0
option_fully_compatible = 1
option_completely_random = 2
default = -1
range_start = 50
range_end = 100
special_range_names = {
"vanilla": -1
}
class TmCompatibility(Choice):
class TmTutorCompatibility(NamedRange):
"""
Modifies the compatibility of TMs
Vanilla: Compatibility is unchanged
Fully Compatible: Every species can learn any TM
Completely Random: Compatibility is 50/50 for every TM (does not remain consistent across evolution)
Sets the percent chance that a given TM or move tutor is compatible with a species
"""
display_name = "TM Compatibility"
default = 0
option_vanilla = 0
option_fully_compatible = 1
option_completely_random = 2
display_name = "TM/Tutor Compatibility"
default = -1
range_start = 0
range_end = 100
special_range_names = {
"vanilla": -1
}
class TmMoves(Toggle):
class TmTutorMoves(Toggle):
"""
Randomizes the moves taught by TMs
Randomizes the moves taught by TMs and move tutors
"""
display_name = "TM Moves"
display_name = "TM/Tutor Moves"
class ReusableTms(Toggle):
class ReusableTmsTutors(Toggle):
"""
Sets TMs to not break after use (they remain sellable)
Sets TMs to not break after use (they remain sellable). Sets move tutors to infinite use.
"""
display_name = "Reusable TMs"
display_name = "Reusable TMs and Tutors"
class MinCatchRate(Range):
@@ -428,6 +567,15 @@ class GuaranteedCatch(Toggle):
display_name = "Guaranteed Catch"
class NormalizeEncounterRates(Toggle):
"""
Make every slot on an encounter table approximately equally likely.
This does NOT mean every species is equally likely. But it will make rarer encounters less rare overall.
"""
display_name = "Normalize Encounter Rates"
class ExpModifier(Range):
"""
Multiplies gained experience by a percentage
@@ -435,7 +583,7 @@ class ExpModifier(Range):
100 is default
50 is half
200 is double
etc...
etc.
"""
display_name = "Exp Modifier"
range_start = 0
@@ -450,6 +598,48 @@ class BlindTrainers(Toggle):
display_name = "Blind Trainers"
class PurgeSpinners(Toggle):
"""
Trainers will rotate in predictable patterns on a set interval instead of randomly and don't turn toward you when you run
"""
display_name = "Purge Spinners"
class MatchTrainerLevels(Choice):
"""
When you start a battle with a trainer, your party's levels will be automatically set to match that trainer's highest level pokemon.
The experience you receive will match your party's average actual level, and will only be awarded when you win the battle.
This is a pseudo-replacement for a level cap and makes every trainer battle a fair fight while still allowing you to level up.
Off: The vanilla experience
Additive: The modifier you apply to your team is a flat bonus
Multiplicative: The modifier you apply to your team is a percent bonus
"""
display_name = "Match Trainer Levels"
default = 0
option_off = 0
option_additive = 1
option_multiplicative = 2
class MatchTrainerLevelsBonus(Range):
"""
A level bonus (or penalty) to apply to your team when matching an opponent's levels.
When the match trainer levels option is "additive", this value is added to your team's levels during a battle.
For example, if this value is 5 (+5 levels), you'll have a level 25 team against a level 20 team, and a level 45 team against a level 40 team.
When the match trainer levels option is "multiplicative", this is a percent bonus.
For example, if this value is 5 (+5%), you'll have a level 21 team against a level 20 team, and a level 42 team against a level 40 team.
"""
display_name = "Match Trainer Levels Modifier"
range_start = -100
range_end = 100
default = 0
class DoubleBattleChance(Range):
"""
The percent chance that a trainer with more than 1 pokemon will be converted into a double battle.
@@ -492,18 +682,34 @@ class RemoveRoadblocks(OptionSet):
"Safari Zone Construction Workers",
"Lilycove City Wailmer",
"Aqua Hideout Grunts",
"Seafloor Cavern Aqua Grunt"
"Seafloor Cavern Aqua Grunt",
])
class ExtraBoulders(Toggle):
"""
Places strength boulders on Route 115 which block access to Meteor Falls from the beach.
This aims to take some power away from Surf as a tool for access.
This aims to take some power away from Surf by restricting how much it allows you to access.
"""
display_name = "Extra Boulders"
class ExtraBumpySlope(Toggle):
"""
Adds a bumpy slope to Route 115 which allows access to Meteor Falls if you have the Acro Bike.
This aims to take some power away from Surf by adding a new way to exit the Rustboro area.
"""
display_name = "Extra Bumpy Slope"
class ModifyRoute118(Toggle):
"""
Changes the layout of Route 118 so that it must be crossed with the Acro Bike instead of Surf.
This aims to take some power away from Surf by restricting how much it allows you to access.
"""
display_name = "Modify Route 118"
class FreeFlyLocation(Toggle):
"""
Enables flying to one random location when Mom gives you the running shoes (excluding cities reachable with no items)
@@ -511,11 +717,14 @@ class FreeFlyLocation(Toggle):
display_name = "Free Fly Location"
class FlyWithoutBadge(DefaultOnToggle):
class HmRequirements(TextChoice):
"""
Fly does not require the Feather Badge to use in the field
Sets the requirements to use HMs outside of battle
"""
display_name = "Fly Without Badge"
display_name = "HM Requirements"
default = 0
option_vanilla = 0
option_fly_without_badge = 1
class TurboA(Toggle):
@@ -540,11 +749,53 @@ class ReceiveItemMessages(Choice):
option_none = 2
class RemoteItems(Toggle):
"""
Instead of placing your own items directly into the ROM, all items are received from the server, including items you find for yourself.
This enables co-op of a single slot and recovering more items after a lost save file (if you're so unlucky).
But it changes pickup behavior slightly and requires connection to the server to receive any items.
"""
display_name = "Remote Items"
class RandomizeMusic(Toggle):
"""
Shuffles music played in any situation where it loops. Includes many FRLG tracks.
"""
display_name = "Randomize Music"
class RandomizeFanfares(Toggle):
"""
Shuffles fanfares for item pickups, healing at the pokecenter, etc.
When this option is enabled, pressing B will interrupt most fanfares.
"""
display_name = "Randomize Fanfares"
class WonderTrading(DefaultOnToggle):
"""
Allows participation in wonder trading with other players in your current multiworld. Speak with the center receptionist on the second floor of any pokecenter.
Wonder trading NEVER affects logic.
Certain aspects of a pokemon species are per-game, not per-pokemon.
As a result, some things are not retained during a trade, including type, ability, level up learnset, and so on.
Receiving a pokemon this way does not mark it as found in your pokedex.
Trade evolutions do not evolve this way; they retain their modified methods (level ups and item use).
"""
display_name = "Wonder Trading"
class EasterEgg(FreeText):
"""
???
Enter certain phrases and something special might happen.
All secret phrases are something that could be a trendy phrase in Dewford Town. They are case insensitive.
"""
default = "Example Passphrase"
default = "EMERALD SECRET"
@dataclass
@@ -555,10 +806,14 @@ class PokemonEmeraldOptions(PerGameCommonOptions):
hms: RandomizeHms
key_items: RandomizeKeyItems
bikes: RandomizeBikes
event_tickets: RandomizeEventTickets
rods: RandomizeRods
overworld_items: RandomizeOverworldItems
hidden_items: RandomizeHiddenItems
npc_gifts: RandomizeNpcGifts
berry_trees: RandomizeBerryTrees
dexsanity: Dexsanity
trainersanity: Trainersanity
item_pool_type: ItemPoolType
require_itemfinder: HiddenItemsRequireItemfinder
@@ -567,14 +822,19 @@ class PokemonEmeraldOptions(PerGameCommonOptions):
elite_four_count: EliteFourCount
norman_requirement: NormanRequirement
norman_count: NormanCount
legendary_hunt_catch: LegendaryHuntCatch
legendary_hunt_count: LegendaryHuntCount
allowed_legendary_hunt_encounters: AllowedLegendaryHuntEncounters
wild_pokemon: RandomizeWildPokemon
allow_wild_legendaries: AllowWildLegendaries
wild_encounter_blacklist: WildEncounterBlacklist
starters: RandomizeStarters
allow_starter_legendaries: AllowStarterLegendaries
starter_blacklist: StarterBlacklist
trainer_parties: RandomizeTrainerParties
allow_trainer_legendaries: AllowTrainerLegendaries
static_encounters: RandomizeStaticEncounters
trainer_party_blacklist: TrainerPartyBlacklist
force_fully_evolved: ForceFullyEvolved
legendary_encounters: RandomizeLegendaryEncounters
misc_pokemon: RandomizeMiscPokemon
types: RandomizeTypes
abilities: RandomizeAbilities
ability_blacklist: AbilityBlacklist
@@ -582,25 +842,38 @@ class PokemonEmeraldOptions(PerGameCommonOptions):
level_up_moves: LevelUpMoves
move_match_type_bias: MoveMatchTypeBias
move_normal_type_bias: MoveNormalTypeBias
tm_compatibility: TmCompatibility
tm_tutor_compatibility: TmTutorCompatibility
hm_compatibility: HmCompatibility
tm_moves: TmMoves
reusable_tms: ReusableTms
tm_tutor_moves: TmTutorMoves
reusable_tms_tutors: ReusableTmsTutors
move_blacklist: MoveBlacklist
min_catch_rate: MinCatchRate
guaranteed_catch: GuaranteedCatch
normalize_encounter_rates: NormalizeEncounterRates
exp_modifier: ExpModifier
blind_trainers: BlindTrainers
purge_spinners: PurgeSpinners
match_trainer_levels: MatchTrainerLevels
match_trainer_levels_bonus: MatchTrainerLevelsBonus
double_battle_chance: DoubleBattleChance
better_shops: BetterShops
enable_ferry: EnableFerry
remove_roadblocks: RemoveRoadblocks
extra_boulders: ExtraBoulders
extra_bumpy_slope: ExtraBumpySlope
modify_118: ModifyRoute118
free_fly_location: FreeFlyLocation
fly_without_badge: FlyWithoutBadge
hm_requirements: HmRequirements
turbo_a: TurboA
receive_item_messages: ReceiveItemMessages
remote_items: RemoteItems
music: RandomizeMusic
fanfares: RandomizeFanfares
death_link: DeathLink
enable_wonder_trading: WonderTrading
easter_egg: EasterEgg