SA2B: v2.0 Content Update (#1294)

Changelog:

Features:
- Completely reworked mission progression system
  - Control of which mission types can be active per-gameplay-style
  - Control of how many missions are active per-gameplay-style
  - Mission order shuffle
- Two new Chaos Emerald Hunt goals
  - `Chaos Emerald Hunt` involves finding the seven Chaos Emeralds and beating Green Hill
  - `FinalHazard Chaos Emerald Hunt` is the same, but with the FinalHazard fight at the end of Green Hill
- New optional Location Checks
  - Keysanity (Chao Containers)
  - Whistlesanity (Animal Pipes and hidden whistle spots)
  - Beetlesanity (Destroying Gold Beetles)
- Option to require clearing all active Cannon's Core Missions for access to the Biolizard fight in `Biolizard` goal
- Hard Logic option
- More Music Options
  - Option to use SADX music
  - New `Singularity` music shuffle option
- Option to choose the Narrator theme 
- New Traps
  - Tiny Trap is now permanent within a level
  - Gravity Trap
  - Exposition Trap
  
Quality of Life:
- Significant revamp to Stage Select screen information conveyance
  - Icons are displayed for:
    - Relevant character's upgrades
    - Which location checks are active/checked
    - Chaos Emeralds found (if relevant)
    - Gate and Cannon's Core emblem costs
  - The above stage-specific info can also be viewed when paused in-level
    - The current mission is also displayed when paused
- Emblem Symbol on Mission Select subscreen now only displays if a high enough rank has been gotten on that mission to send the location check
- Hints including SA2B locations will now specify which Gate that level is located in
- Save file now stores slot name to help prevent false location checks in the case of one player having multiple SA2B slots in the same seed
- Chao Intermediate and Expert race sets are now swapped, per player feedback
  - Intermediate now includes Beginner + Challenge + Hero + Dark
  - Expert now includes Beginner + Challenge + Hero + Dark + Jewel
- New mod config option for the color of the Message Queue text

Bug Fixes:
- Fixed bug where game stops properly tracking items after 127 have been received.
- Several logic fixes
- Game now refers to `Knuckles - Shovel Claws` correctly
- Minor AP World code cleanup
This commit is contained in:
PoryGone 2022-12-07 00:20:02 -05:00 committed by GitHub
parent f5638552cc
commit 449973687b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 3026 additions and 669 deletions

View File

@ -72,10 +72,23 @@ junk_table = {
} }
trap_table = { trap_table = {
ItemName.omochao_trap: ItemData(0xFF0030, False, True), ItemName.omochao_trap: ItemData(0xFF0030, False, True),
ItemName.timestop_trap: ItemData(0xFF0031, False, True), ItemName.timestop_trap: ItemData(0xFF0031, False, True),
ItemName.confuse_trap: ItemData(0xFF0032, False, True), ItemName.confuse_trap: ItemData(0xFF0032, False, True),
ItemName.tiny_trap: ItemData(0xFF0033, False, True), ItemName.tiny_trap: ItemData(0xFF0033, False, True),
ItemName.gravity_trap: ItemData(0xFF0034, False, True),
ItemName.exposition_trap: ItemData(0xFF0035, False, True),
#ItemName.darkness_trap: ItemData(0xFF0036, False, True),
}
emeralds_table = {
ItemName.white_emerald: ItemData(0xFF0040, True),
ItemName.red_emerald: ItemData(0xFF0041, True),
ItemName.cyan_emerald: ItemData(0xFF0042, True),
ItemName.purple_emerald: ItemData(0xFF0043, True),
ItemName.green_emerald: ItemData(0xFF0044, True),
ItemName.yellow_emerald: ItemData(0xFF0045, True),
ItemName.blue_emerald: ItemData(0xFF0046, True),
} }
event_table = { event_table = {
@ -88,10 +101,13 @@ item_table = {
**upgrades_table, **upgrades_table,
**junk_table, **junk_table,
**trap_table, **trap_table,
**emeralds_table,
**event_table, **event_table,
} }
lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in item_table.items() if data.code} lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in item_table.items() if data.code}
item_groups: typing.Dict[str, str] = {"Chaos Emeralds": [item_name for item_name, data in emeralds_table.items()]}
ALTTPWorld.pedestal_credit_texts[item_table[ItemName.sonic_light_shoes].code] = "and the Soap Shoes" ALTTPWorld.pedestal_credit_texts[item_table[ItemName.sonic_light_shoes].code] = "and the Soap Shoes"
ALTTPWorld.pedestal_credit_texts[item_table[ItemName.shadow_air_shoes].code] = "and the Soap Shoes" ALTTPWorld.pedestal_credit_texts[item_table[ItemName.shadow_air_shoes].code] = "and the Soap Shoes"

View File

@ -1,14 +1,15 @@
import typing import typing
from BaseClasses import Location from BaseClasses import Location, MultiWorld
from .Names import LocationName from .Names import LocationName
from .Missions import stage_name_prefixes, mission_orders
class SA2BLocation(Location): class SA2BLocation(Location):
game: str = "Sonic Adventure 2: Battle" game: str = "Sonic Adventure 2: Battle"
first_mission_location_table = { mission_location_table = {
LocationName.city_escape_1: 0xFF0000, LocationName.city_escape_1: 0xFF0000,
LocationName.wild_canyon_1: 0xFF0001, LocationName.wild_canyon_1: 0xFF0001,
LocationName.prison_lane_1: 0xFF0002, LocationName.prison_lane_1: 0xFF0002,
@ -42,9 +43,8 @@ first_mission_location_table = {
LocationName.final_chase_1: 0xFF001D, LocationName.final_chase_1: 0xFF001D,
LocationName.cannon_core_1: 0xFF001E, LocationName.cannon_core_1: 0xFF001E,
}
second_mission_location_table = {
LocationName.city_escape_2: 0xFF0020, LocationName.city_escape_2: 0xFF0020,
LocationName.wild_canyon_2: 0xFF0021, LocationName.wild_canyon_2: 0xFF0021,
LocationName.prison_lane_2: 0xFF0022, LocationName.prison_lane_2: 0xFF0022,
@ -78,9 +78,8 @@ second_mission_location_table = {
LocationName.final_chase_2: 0xFF003D, LocationName.final_chase_2: 0xFF003D,
LocationName.cannon_core_2: 0xFF003E, LocationName.cannon_core_2: 0xFF003E,
}
third_mission_location_table = {
LocationName.city_escape_3: 0xFF0040, LocationName.city_escape_3: 0xFF0040,
LocationName.wild_canyon_3: 0xFF0041, LocationName.wild_canyon_3: 0xFF0041,
LocationName.prison_lane_3: 0xFF0042, LocationName.prison_lane_3: 0xFF0042,
@ -114,9 +113,8 @@ third_mission_location_table = {
LocationName.final_chase_3: 0xFF005D, LocationName.final_chase_3: 0xFF005D,
LocationName.cannon_core_3: 0xFF005E, LocationName.cannon_core_3: 0xFF005E,
}
fourth_mission_location_table = {
LocationName.city_escape_4: 0xFF0060, LocationName.city_escape_4: 0xFF0060,
LocationName.wild_canyon_4: 0xFF0061, LocationName.wild_canyon_4: 0xFF0061,
LocationName.prison_lane_4: 0xFF0062, LocationName.prison_lane_4: 0xFF0062,
@ -150,9 +148,8 @@ fourth_mission_location_table = {
LocationName.final_chase_4: 0xFF007D, LocationName.final_chase_4: 0xFF007D,
LocationName.cannon_core_4: 0xFF007E, LocationName.cannon_core_4: 0xFF007E,
}
fifth_mission_location_table = {
LocationName.city_escape_5: 0xFF0080, LocationName.city_escape_5: 0xFF0080,
LocationName.wild_canyon_5: 0xFF0081, LocationName.wild_canyon_5: 0xFF0081,
LocationName.prison_lane_5: 0xFF0082, LocationName.prison_lane_5: 0xFF0082,
@ -220,6 +217,292 @@ upgrade_location_table = {
LocationName.final_chase_upgrade: 0xFF00BD, LocationName.final_chase_upgrade: 0xFF00BD,
} }
chao_key_location_table = {
LocationName.city_escape_chao_1: 0xFF0400,
LocationName.wild_canyon_chao_1: 0xFF0401,
LocationName.prison_lane_chao_1: 0xFF0402,
LocationName.metal_harbor_chao_1: 0xFF0403,
LocationName.green_forest_chao_1: 0xFF0404,
LocationName.pumpkin_hill_chao_1: 0xFF0405,
LocationName.mission_street_chao_1: 0xFF0406,
LocationName.aquatic_mine_chao_1: 0xFF0407,
LocationName.hidden_base_chao_1: 0xFF0409,
LocationName.pyramid_cave_chao_1: 0xFF040A,
LocationName.death_chamber_chao_1: 0xFF040B,
LocationName.eternal_engine_chao_1: 0xFF040C,
LocationName.meteor_herd_chao_1: 0xFF040D,
LocationName.crazy_gadget_chao_1: 0xFF040E,
LocationName.final_rush_chao_1: 0xFF040F,
LocationName.iron_gate_chao_1: 0xFF0410,
LocationName.dry_lagoon_chao_1: 0xFF0411,
LocationName.sand_ocean_chao_1: 0xFF0412,
LocationName.radical_highway_chao_1: 0xFF0413,
LocationName.egg_quarters_chao_1: 0xFF0414,
LocationName.lost_colony_chao_1: 0xFF0415,
LocationName.weapons_bed_chao_1: 0xFF0416,
LocationName.security_hall_chao_1: 0xFF0417,
LocationName.white_jungle_chao_1: 0xFF0418,
LocationName.sky_rail_chao_1: 0xFF041A,
LocationName.mad_space_chao_1: 0xFF041B,
LocationName.cosmic_wall_chao_1: 0xFF041C,
LocationName.final_chase_chao_1: 0xFF041D,
LocationName.cannon_core_chao_1: 0xFF041E,
LocationName.city_escape_chao_2: 0xFF0420,
LocationName.wild_canyon_chao_2: 0xFF0421,
LocationName.prison_lane_chao_2: 0xFF0422,
LocationName.metal_harbor_chao_2: 0xFF0423,
LocationName.green_forest_chao_2: 0xFF0424,
LocationName.pumpkin_hill_chao_2: 0xFF0425,
LocationName.mission_street_chao_2: 0xFF0426,
LocationName.aquatic_mine_chao_2: 0xFF0427,
LocationName.hidden_base_chao_2: 0xFF0429,
LocationName.pyramid_cave_chao_2: 0xFF042A,
LocationName.death_chamber_chao_2: 0xFF042B,
LocationName.eternal_engine_chao_2: 0xFF042C,
LocationName.meteor_herd_chao_2: 0xFF042D,
LocationName.crazy_gadget_chao_2: 0xFF042E,
LocationName.final_rush_chao_2: 0xFF042F,
LocationName.iron_gate_chao_2: 0xFF0430,
LocationName.dry_lagoon_chao_2: 0xFF0431,
LocationName.sand_ocean_chao_2: 0xFF0432,
LocationName.radical_highway_chao_2: 0xFF0433,
LocationName.egg_quarters_chao_2: 0xFF0434,
LocationName.lost_colony_chao_2: 0xFF0435,
LocationName.weapons_bed_chao_2: 0xFF0436,
LocationName.security_hall_chao_2: 0xFF0437,
LocationName.white_jungle_chao_2: 0xFF0438,
LocationName.sky_rail_chao_2: 0xFF043A,
LocationName.mad_space_chao_2: 0xFF043B,
LocationName.cosmic_wall_chao_2: 0xFF043C,
LocationName.final_chase_chao_2: 0xFF043D,
LocationName.cannon_core_chao_2: 0xFF043E,
LocationName.city_escape_chao_3: 0xFF0440,
LocationName.wild_canyon_chao_3: 0xFF0441,
LocationName.prison_lane_chao_3: 0xFF0442,
LocationName.metal_harbor_chao_3: 0xFF0443,
LocationName.green_forest_chao_3: 0xFF0444,
LocationName.pumpkin_hill_chao_3: 0xFF0445,
LocationName.mission_street_chao_3: 0xFF0446,
LocationName.aquatic_mine_chao_3: 0xFF0447,
LocationName.pyramid_cave_chao_3: 0xFF044A,
LocationName.death_chamber_chao_3: 0xFF044B,
LocationName.eternal_engine_chao_3: 0xFF044C,
LocationName.meteor_herd_chao_3: 0xFF044D,
LocationName.crazy_gadget_chao_3: 0xFF044E,
LocationName.final_rush_chao_3: 0xFF044F,
LocationName.iron_gate_chao_3: 0xFF0450,
LocationName.dry_lagoon_chao_3: 0xFF0451,
LocationName.sand_ocean_chao_3: 0xFF0452,
LocationName.radical_highway_chao_3: 0xFF0453,
LocationName.egg_quarters_chao_3: 0xFF0454,
LocationName.lost_colony_chao_3: 0xFF0455,
LocationName.weapons_bed_chao_3: 0xFF0456,
LocationName.security_hall_chao_3: 0xFF0457,
LocationName.white_jungle_chao_3: 0xFF0458,
LocationName.sky_rail_chao_3: 0xFF045A,
LocationName.mad_space_chao_3: 0xFF045B,
LocationName.cosmic_wall_chao_3: 0xFF045C,
LocationName.final_chase_chao_3: 0xFF045D,
LocationName.cannon_core_chao_3: 0xFF045E,
}
pipe_location_table = {
LocationName.city_escape_pipe_1: 0xFF0500,
LocationName.wild_canyon_pipe_1: 0xFF0501,
LocationName.prison_lane_pipe_1: 0xFF0502,
LocationName.metal_harbor_pipe_1: 0xFF0503,
LocationName.green_forest_pipe_1: 0xFF0504,
LocationName.pumpkin_hill_pipe_1: 0xFF0505,
LocationName.mission_street_pipe_1: 0xFF0506,
LocationName.aquatic_mine_pipe_1: 0xFF0507,
LocationName.hidden_base_pipe_1: 0xFF0509,
LocationName.pyramid_cave_pipe_1: 0xFF050A,
LocationName.death_chamber_pipe_1: 0xFF050B,
LocationName.eternal_engine_pipe_1: 0xFF050C,
LocationName.meteor_herd_pipe_1: 0xFF050D,
LocationName.crazy_gadget_pipe_1: 0xFF050E,
LocationName.final_rush_pipe_1: 0xFF050F,
LocationName.iron_gate_pipe_1: 0xFF0510,
LocationName.dry_lagoon_pipe_1: 0xFF0511,
LocationName.sand_ocean_pipe_1: 0xFF0512,
LocationName.radical_highway_pipe_1: 0xFF0513,
LocationName.egg_quarters_pipe_1: 0xFF0514,
LocationName.lost_colony_pipe_1: 0xFF0515,
LocationName.weapons_bed_pipe_1: 0xFF0516,
LocationName.security_hall_pipe_1: 0xFF0517,
LocationName.white_jungle_pipe_1: 0xFF0518,
LocationName.sky_rail_pipe_1: 0xFF051A,
LocationName.mad_space_pipe_1: 0xFF051B,
LocationName.cosmic_wall_pipe_1: 0xFF051C,
LocationName.final_chase_pipe_1: 0xFF051D,
LocationName.cannon_core_pipe_1: 0xFF051E,
LocationName.city_escape_pipe_2: 0xFF0520,
LocationName.wild_canyon_pipe_2: 0xFF0521,
LocationName.prison_lane_pipe_2: 0xFF0522,
LocationName.green_forest_pipe_2: 0xFF0524,
LocationName.mission_street_pipe_2: 0xFF0526,
LocationName.aquatic_mine_pipe_2: 0xFF0527,
LocationName.hidden_base_pipe_2: 0xFF0529,
LocationName.pyramid_cave_pipe_2: 0xFF052A,
LocationName.death_chamber_pipe_2: 0xFF052B,
LocationName.eternal_engine_pipe_2: 0xFF052C,
LocationName.meteor_herd_pipe_2: 0xFF052D,
LocationName.crazy_gadget_pipe_2: 0xFF052E,
LocationName.final_rush_pipe_2: 0xFF052F,
LocationName.iron_gate_pipe_2: 0xFF0530,
LocationName.sand_ocean_pipe_2: 0xFF0532,
LocationName.radical_highway_pipe_2: 0xFF0533,
LocationName.egg_quarters_pipe_2: 0xFF0534,
LocationName.lost_colony_pipe_2: 0xFF0535,
LocationName.weapons_bed_pipe_2: 0xFF0536,
LocationName.white_jungle_pipe_2: 0xFF0538,
LocationName.sky_rail_pipe_2: 0xFF053A,
LocationName.mad_space_pipe_2: 0xFF053B,
LocationName.cosmic_wall_pipe_2: 0xFF053C,
LocationName.final_chase_pipe_2: 0xFF053D,
LocationName.cannon_core_pipe_2: 0xFF053E,
LocationName.city_escape_pipe_3: 0xFF0540,
LocationName.wild_canyon_pipe_3: 0xFF0541,
LocationName.prison_lane_pipe_3: 0xFF0542,
LocationName.mission_street_pipe_3: 0xFF0546,
LocationName.aquatic_mine_pipe_3: 0xFF0547,
LocationName.hidden_base_pipe_3: 0xFF0549,
LocationName.pyramid_cave_pipe_3: 0xFF054A,
LocationName.death_chamber_pipe_3: 0xFF054B,
LocationName.eternal_engine_pipe_3: 0xFF054C,
LocationName.meteor_herd_pipe_3: 0xFF054D,
LocationName.crazy_gadget_pipe_3: 0xFF054E,
LocationName.iron_gate_pipe_3: 0xFF0550,
LocationName.sand_ocean_pipe_3: 0xFF0552,
LocationName.radical_highway_pipe_3: 0xFF0553,
LocationName.weapons_bed_pipe_3: 0xFF0556,
LocationName.white_jungle_pipe_3: 0xFF0558,
LocationName.sky_rail_pipe_3: 0xFF055A,
LocationName.mad_space_pipe_3: 0xFF055B,
LocationName.cosmic_wall_pipe_3: 0xFF055C,
LocationName.final_chase_pipe_3: 0xFF055D,
LocationName.cannon_core_pipe_3: 0xFF055E,
LocationName.city_escape_pipe_4: 0xFF0560,
LocationName.hidden_base_pipe_4: 0xFF0569,
LocationName.pyramid_cave_pipe_4: 0xFF056A,
LocationName.eternal_engine_pipe_4: 0xFF056C,
LocationName.crazy_gadget_pipe_4: 0xFF056E,
LocationName.iron_gate_pipe_4: 0xFF0570,
LocationName.sand_ocean_pipe_4: 0xFF0572,
LocationName.weapons_bed_pipe_4: 0xFF0576,
LocationName.white_jungle_pipe_4: 0xFF0578,
LocationName.sky_rail_pipe_4: 0xFF057A,
LocationName.mad_space_pipe_4: 0xFF057B,
LocationName.cosmic_wall_pipe_4: 0xFF057C,
LocationName.cannon_core_pipe_4: 0xFF057E,
LocationName.hidden_base_pipe_5: 0xFF0589,
LocationName.eternal_engine_pipe_5: 0xFF058C,
LocationName.iron_gate_pipe_5: 0xFF0590,
LocationName.sand_ocean_pipe_5: 0xFF0592,
LocationName.weapons_bed_pipe_5: 0xFF0596,
LocationName.sky_rail_pipe_5: 0xFF059A,
LocationName.cosmic_wall_pipe_5: 0xFF059C,
LocationName.cannon_core_pipe_5: 0xFF059E,
LocationName.sky_rail_pipe_6: 0xFF05BA,
}
hidden_whistle_location_table = {
LocationName.city_escape_hidden_1: 0xFF0700,
LocationName.prison_lane_hidden_1: 0xFF0702,
LocationName.green_forest_hidden_1: 0xFF0704,
LocationName.pumpkin_hill_hidden_1: 0xFF0705,
LocationName.mission_street_hidden_1: 0xFF0706,
LocationName.death_chamber_hidden_1: 0xFF070B,
LocationName.crazy_gadget_hidden_1: 0xFF070E,
LocationName.dry_lagoon_hidden_1: 0xFF0711,
LocationName.radical_highway_hidden_1: 0xFF0713,
LocationName.egg_quarters_hidden_1: 0xFF0714,
LocationName.lost_colony_hidden_1: 0xFF0715,
LocationName.security_hall_hidden_1: 0xFF0717,
LocationName.white_jungle_hidden_1: 0xFF0718,
LocationName.cannon_core_hidden_1: 0xFF071E,
LocationName.city_escape_hidden_2: 0xFF0720,
LocationName.prison_lane_hidden_2: 0xFF0722,
LocationName.green_forest_hidden_2: 0xFF0724,
LocationName.mission_street_hidden_2: 0xFF0726,
LocationName.death_chamber_hidden_2: 0xFF072B,
LocationName.radical_highway_hidden_2: 0xFF0733,
LocationName.egg_quarters_hidden_2: 0xFF0734,
LocationName.white_jungle_hidden_2: 0xFF0738,
LocationName.city_escape_hidden_3: 0xFF0740,
LocationName.prison_lane_hidden_3: 0xFF0742,
LocationName.green_forest_hidden_3: 0xFF0744,
LocationName.mission_street_hidden_3: 0xFF0746,
LocationName.radical_highway_hidden_3: 0xFF0753,
LocationName.white_jungle_hidden_3: 0xFF0758,
LocationName.city_escape_hidden_4: 0xFF0760,
LocationName.green_forest_hidden_4: 0xFF0764,
LocationName.city_escape_hidden_5: 0xFF0780,
}
beetle_location_table = {
LocationName.city_escape_beetle: 0xFF0600,
LocationName.wild_canyon_beetle: 0xFF0601,
LocationName.prison_lane_beetle: 0xFF0602,
LocationName.metal_harbor_beetle: 0xFF0603,
LocationName.green_forest_beetle: 0xFF0604,
LocationName.mission_street_beetle: 0xFF0606,
LocationName.aquatic_mine_beetle: 0xFF0607,
LocationName.hidden_base_beetle: 0xFF0609,
LocationName.pyramid_cave_beetle: 0xFF060A,
LocationName.death_chamber_beetle: 0xFF060B,
LocationName.eternal_engine_beetle: 0xFF060C,
LocationName.meteor_herd_beetle: 0xFF060D,
LocationName.crazy_gadget_beetle: 0xFF060E,
LocationName.final_rush_beetle: 0xFF060F,
LocationName.iron_gate_beetle: 0xFF0610,
LocationName.dry_lagoon_beetle: 0xFF0611,
LocationName.sand_ocean_beetle: 0xFF0612,
LocationName.radical_highway_beetle: 0xFF0613,
LocationName.egg_quarters_beetle: 0xFF0614,
LocationName.lost_colony_beetle: 0xFF0615,
LocationName.security_hall_beetle: 0xFF0617,
LocationName.white_jungle_beetle: 0xFF0618,
LocationName.sky_rail_beetle: 0xFF061A,
LocationName.mad_space_beetle: 0xFF061B,
LocationName.cosmic_wall_beetle: 0xFF061C,
LocationName.final_chase_beetle: 0xFF061D,
LocationName.cannon_core_beetle: 0xFF061E,
}
boss_gate_location_table = { boss_gate_location_table = {
LocationName.gate_1_boss: 0xFF0100, LocationName.gate_1_boss: 0xFF0100,
LocationName.gate_2_boss: 0xFF0101, LocationName.gate_2_boss: 0xFF0101,
@ -308,23 +591,33 @@ chao_garden_expert_location_table = {
LocationName.chao_super_karate: 0xFF0303, LocationName.chao_super_karate: 0xFF0303,
} }
other_location_table = { green_hill_location_table = {
# LocationName.green_hill: 0xFF001F, LocationName.green_hill: 0xFF001F,
LocationName.biolizard: 0xFF003F, }
green_hill_chao_location_table = {
LocationName.green_hill_chao_1: 0xFF041F,
}
final_boss_location_table = {
# LocationName.biolizard: 0xFF003F,
LocationName.finalhazard: 0xFF005F,
} }
all_locations = { all_locations = {
**first_mission_location_table, **mission_location_table,
**second_mission_location_table,
**third_mission_location_table,
**fourth_mission_location_table,
**fifth_mission_location_table,
**upgrade_location_table, **upgrade_location_table,
**boss_gate_location_table, **boss_gate_location_table,
**chao_key_location_table,
**pipe_location_table,
**hidden_whistle_location_table,
**beetle_location_table,
**chao_garden_beginner_location_table, **chao_garden_beginner_location_table,
**chao_garden_intermediate_location_table, **chao_garden_intermediate_location_table,
**chao_garden_expert_location_table, **chao_garden_expert_location_table,
**other_location_table, **green_hill_location_table,
**green_hill_chao_location_table,
**final_boss_location_table,
} }
boss_gate_set = [ boss_gate_set = [
@ -367,26 +660,45 @@ chao_race_prize_set = [
] ]
def setup_locations(world, player: int): def setup_locations(world: MultiWorld, player: int, mission_map: typing.Dict[int, int], mission_count_map: typing.Dict[int, int]):
location_table = {} location_table = {}
chao_location_table = {} chao_location_table = {}
location_table.update({**first_mission_location_table})
if world.include_missions[player].value >= 2:
location_table.update({**second_mission_location_table})
if world.include_missions[player].value >= 3: for i in range(31):
location_table.update({**third_mission_location_table}) mission_count = mission_count_map[i]
mission_order: typing.List[int] = mission_orders[mission_map[i]]
stage_prefix: str = stage_name_prefixes[i]
if world.include_missions[player].value >= 4: for j in range(mission_count):
location_table.update({**fourth_mission_location_table}) mission_number = mission_order[j]
location_name: str = stage_prefix + str(mission_number)
if world.include_missions[player].value >= 5: location_table[location_name] = mission_location_table[location_name]
location_table.update({**fifth_mission_location_table})
location_table.update({**upgrade_location_table}) location_table.update({**upgrade_location_table})
location_table.update({**other_location_table}) if world.keysanity[player]:
location_table.update({**chao_key_location_table})
if world.whistlesanity[player].value == 1:
location_table.update({**pipe_location_table})
elif world.whistlesanity[player].value == 2:
location_table.update({**hidden_whistle_location_table})
elif world.whistlesanity[player].value == 3:
location_table.update({**pipe_location_table})
location_table.update({**hidden_whistle_location_table})
if world.beetlesanity[player]:
location_table.update({**beetle_location_table})
if world.goal[player].value == 0 or world.goal[player].value == 2:
location_table.update({**final_boss_location_table})
if world.goal[player].value == 1 or world.goal[player].value == 2:
location_table.update({**green_hill_location_table})
if world.keysanity[player]:
location_table.update({**green_hill_chao_location_table})
if world.chao_garden_difficulty[player].value >= 1: if world.chao_garden_difficulty[player].value >= 1:
chao_location_table.update({**chao_garden_beginner_location_table}) chao_location_table.update({**chao_garden_beginner_location_table})

327
worlds/sa2b/Missions.py Normal file
View File

@ -0,0 +1,327 @@
import typing
import copy
from BaseClasses import MultiWorld
mission_orders: typing.List[typing.List[int]] = [
[1, 2, 3, 4, 5],
[1, 2, 3, 5, 4],
[1, 2, 4, 3, 5],
[1, 2, 4, 5, 3],
[1, 2, 5, 3, 4],
[1, 2, 5, 4, 3],
[1, 3, 2, 4, 5],
[1, 3, 2, 5, 4],
[1, 3, 4, 2, 5],
[1, 3, 4, 5, 2],
[1, 3, 5, 2, 4],
[1, 3, 5, 4, 2],
[1, 4, 2, 3, 5],
[1, 4, 2, 5, 3],
[1, 4, 3, 2, 5],
[1, 4, 3, 5, 2],
[1, 4, 5, 2, 3],
[1, 4, 5, 3, 2],
[1, 5, 2, 3, 4],
[1, 5, 2, 4, 3],
[1, 5, 3, 2, 4],
[1, 5, 3, 4, 2],
[1, 5, 4, 2, 3],
[1, 5, 4, 3, 2],
[2, 1, 3, 4, 5],
[2, 1, 3, 5, 4],
[2, 1, 4, 3, 5],
[2, 1, 4, 5, 3],
[2, 1, 5, 3, 4],
[2, 1, 5, 4, 3],
[2, 3, 1, 4, 5],
[2, 3, 1, 5, 4],
[2, 3, 4, 1, 5],
[2, 3, 4, 5, 1],
[2, 3, 5, 1, 4],
[2, 3, 5, 4, 1],
[2, 4, 1, 3, 5],
[2, 4, 1, 5, 3],
[2, 4, 3, 1, 5],
[2, 4, 3, 5, 1],
[2, 4, 5, 1, 3],
[2, 4, 5, 3, 1],
[2, 5, 1, 3, 4],
[2, 5, 1, 4, 3],
[2, 5, 3, 1, 4],
[2, 5, 3, 4, 1],
[2, 5, 4, 1, 3],
[2, 5, 4, 3, 1],
[3, 1, 2, 4, 5],
[3, 1, 2, 5, 4],
[3, 1, 4, 2, 5],
[3, 1, 4, 5, 2],
[3, 1, 5, 4, 2],
[3, 1, 5, 2, 4],
[3, 2, 1, 4, 5],
[3, 2, 1, 5, 4],
[3, 2, 4, 1, 5],
[3, 2, 4, 5, 1],
[3, 2, 5, 1, 4],
[3, 2, 5, 4, 1],
[3, 4, 1, 2, 5],
[3, 4, 1, 5, 2],
[3, 4, 2, 1, 5],
[3, 4, 2, 5, 1],
[3, 4, 5, 1, 2],
[3, 4, 5, 2, 1],
[3, 5, 1, 4, 2],
[3, 5, 1, 2, 4],
[3, 5, 2, 1, 4],
[3, 5, 2, 4, 1],
[3, 5, 4, 1, 2],
[3, 5, 4, 2, 1],
[4, 1, 2, 3, 5],
[4, 1, 2, 5, 3],
[4, 1, 3, 2, 5],
[4, 1, 3, 5, 2],
[4, 1, 5, 3, 2],
[4, 1, 5, 2, 3],
[4, 2, 1, 3, 5],
[4, 2, 1, 5, 3],
[4, 2, 3, 1, 5],
[4, 2, 3, 5, 1],
[4, 2, 5, 1, 3],
[4, 2, 5, 3, 1],
[4, 3, 1, 2, 5],
[4, 3, 1, 5, 2],
[4, 3, 2, 1, 5],
[4, 3, 2, 5, 1],
[4, 3, 5, 1, 2],
[4, 3, 5, 2, 1],
[4, 5, 1, 3, 2],
[4, 5, 1, 2, 3],
[4, 5, 2, 1, 3],
[4, 5, 2, 3, 1],
[4, 5, 3, 1, 2],
[4, 5, 3, 2, 1],
]
### 0: Speed
### 1: Mech
### 2: Hunt
### 3: Kart
### 4: Cannon's Core
level_styles: typing.List[int] = [
0,
2,
1,
0,
0,
2,
1,
2,
3,
1,
0,
2,
1,
2,
0,
0,
1,
2,
1,
0,
2,
1,
1,
2,
0,
3,
0,
2,
1,
0,
4,
]
stage_name_prefixes: typing.List[str] = [
"City Escape - ",
"Wild Canyon - ",
"Prison Lane - ",
"Metal Harbor - ",
"Green Forest - ",
"Pumpkin Hill - ",
"Mission Street - ",
"Aquatic Mine - ",
"Route 101 - ",
"Hidden Base - ",
"Pyramid Cave - ",
"Death Chamber - ",
"Eternal Engine - ",
"Meteor Herd - ",
"Crazy Gadget - ",
"Final Rush - ",
"Iron Gate - ",
"Dry Lagoon - ",
"Sand Ocean - ",
"Radical Highway - ",
"Egg Quarters - ",
"Lost Colony - ",
"Weapons Bed - ",
"Security Hall - ",
"White Jungle - ",
"Route 280 - ",
"Sky Rail - ",
"Mad Space - ",
"Cosmic Wall - ",
"Final Chase - ",
"Cannon Core - ",
]
def get_mission_count_table(multiworld: MultiWorld, player: int):
speed_active_missions = 1
mech_active_missions = 1
hunt_active_missions = 1
kart_active_missions = 1
cannons_core_active_missions = 1
for i in range(2,6):
if getattr(multiworld, "speed_mission_" + str(i), None)[player]:
speed_active_missions += 1
if getattr(multiworld, "mech_mission_" + str(i), None)[player]:
mech_active_missions += 1
if getattr(multiworld, "hunt_mission_" + str(i), None)[player]:
hunt_active_missions += 1
if getattr(multiworld, "kart_mission_" + str(i), None)[player]:
kart_active_missions += 1
if getattr(multiworld, "cannons_core_mission_" + str(i), None)[player]:
cannons_core_active_missions += 1
speed_active_missions = min(speed_active_missions, multiworld.speed_mission_count[player].value)
mech_active_missions = min(mech_active_missions, multiworld.mech_mission_count[player].value)
hunt_active_missions = min(hunt_active_missions, multiworld.hunt_mission_count[player].value)
kart_active_missions = min(kart_active_missions, multiworld.kart_mission_count[player].value)
cannons_core_active_missions = min(cannons_core_active_missions, multiworld.cannons_core_mission_count[player].value)
active_missions: typing.List[typing.List[int]] = [
speed_active_missions,
mech_active_missions,
hunt_active_missions,
kart_active_missions,
cannons_core_active_missions
]
mission_count_table: typing.Dict[int, int] = {}
for level in range(31):
level_style = level_styles[level]
level_mission_count = active_missions[level_style]
mission_count_table[level] = level_mission_count
return mission_count_table
def get_mission_table(multiworld: MultiWorld, player: int):
mission_table: typing.Dict[int, int] = {}
speed_active_missions: typing.List[int] = [1]
mech_active_missions: typing.List[int] = [1]
hunt_active_missions: typing.List[int] = [1]
kart_active_missions: typing.List[int] = [1]
cannons_core_active_missions: typing.List[int] = [1]
# Add included missions
for i in range(2,6):
if getattr(multiworld, "speed_mission_" + str(i), None)[player]:
speed_active_missions.append(i)
if getattr(multiworld, "mech_mission_" + str(i), None)[player]:
mech_active_missions.append(i)
if getattr(multiworld, "hunt_mission_" + str(i), None)[player]:
hunt_active_missions.append(i)
if getattr(multiworld, "kart_mission_" + str(i), None)[player]:
kart_active_missions.append(i)
if getattr(multiworld, "cannons_core_mission_" + str(i), None)[player]:
cannons_core_active_missions.append(i)
active_missions: typing.List[typing.List[int]] = [
speed_active_missions,
mech_active_missions,
hunt_active_missions,
kart_active_missions,
cannons_core_active_missions
]
for level in range(31):
level_style = level_styles[level]
level_active_missions: typing.List[int] = copy.deepcopy(active_missions[level_style])
level_chosen_missions: typing.List[int] = []
# The first mission must be M1, M2, or M4
first_mission = 1
if multiworld.mission_shuffle[player]:
first_mission = multiworld.random.choice([mission for mission in level_active_missions if mission in [1, 2, 3, 4]])
level_active_missions.remove(first_mission)
# Place Active Missions in the chosen mission list
for mission in level_active_missions:
if mission not in level_chosen_missions:
level_chosen_missions.append(mission)
if multiworld.mission_shuffle[player]:
multiworld.random.shuffle(level_chosen_missions)
level_chosen_missions.insert(0, first_mission)
# Fill in the non-included missions
for i in range(2,6):
if i not in level_chosen_missions:
level_chosen_missions.append(i)
# Determine which mission order index we have, for conveying to the mod
for i in range(len(mission_orders)):
if mission_orders[i] == level_chosen_missions:
level_mission_index = i
break
mission_table[level] = level_mission_index
return mission_table
def get_first_and_last_cannons_core_missions(mission_map: typing.Dict[int, int], mission_count_map: typing.Dict[int, int]):
mission_count = mission_count_map[30]
mission_order: typing.List[int] = mission_orders[mission_map[30]]
stage_prefix: str = stage_name_prefixes[30]
first_mission_number = mission_order[0]
last_mission_number = mission_order[mission_count - 1]
first_location_name: str = stage_prefix + str(first_mission_number)
last_location_name: str = stage_prefix + str(last_mission_number)
return first_location_name, last_location_name

View File

@ -44,9 +44,20 @@ shield = "Shield"
magnetic_shield = "Magnetic Shield" magnetic_shield = "Magnetic Shield"
invincibility = "Invincibility" invincibility = "Invincibility"
omochao_trap = "OmoTrap" omochao_trap = "OmoTrap"
timestop_trap = "Chaos Control Trap" timestop_trap = "Chaos Control Trap"
confuse_trap = "Confusion Trap" confuse_trap = "Confusion Trap"
tiny_trap = "Tiny Trap" tiny_trap = "Tiny Trap"
gravity_trap = "Gravity Trap"
exposition_trap = "Exposition Trap"
darkness_trap = "Darkness Trap"
white_emerald = "White Chaos Emerald"
red_emerald = "Red Chaos Emerald"
cyan_emerald = "Cyan Chaos Emerald"
purple_emerald = "Purple Chaos Emerald"
green_emerald = "Green Chaos Emerald"
yellow_emerald = "Yellow Chaos Emerald"
blue_emerald = "Blue Chaos Emerald"
maria = "What Maria Wanted" maria = "What Maria Wanted"

View File

@ -1,200 +1,441 @@
# Sonic Mission Definitions # Sonic Mission Definitions
city_escape_1 = "City Escape - 1" city_escape_1 = "City Escape - 1"
city_escape_2 = "City Escape - 2" city_escape_2 = "City Escape - 2"
city_escape_3 = "City Escape - 3" city_escape_3 = "City Escape - 3"
city_escape_4 = "City Escape - 4" city_escape_4 = "City Escape - 4"
city_escape_5 = "City Escape - 5" city_escape_5 = "City Escape - 5"
city_escape_upgrade = "City Escape - Upgrade" city_escape_chao_1 = "City Escape - Chao Key 1"
metal_harbor_1 = "Metal Harbor - 1" city_escape_chao_2 = "City Escape - Chao Key 2"
metal_harbor_2 = "Metal Harbor - 2" city_escape_chao_3 = "City Escape - Chao Key 3"
metal_harbor_3 = "Metal Harbor - 3" city_escape_pipe_1 = "City Escape - Pipe 1"
metal_harbor_4 = "Metal Harbor - 4" city_escape_pipe_2 = "City Escape - Pipe 2"
metal_harbor_5 = "Metal Harbor - 5" city_escape_pipe_3 = "City Escape - Pipe 3"
metal_harbor_upgrade = "Metal Harbor - Upgrade" city_escape_pipe_4 = "City Escape - Pipe 4"
green_forest_1 = "Green Forest - 1" city_escape_hidden_1 = "City Escape - Hidden 1"
green_forest_2 = "Green Forest - 2" city_escape_hidden_2 = "City Escape - Hidden 2"
green_forest_3 = "Green Forest - 3" city_escape_hidden_3 = "City Escape - Hidden 3"
green_forest_4 = "Green Forest - 4" city_escape_hidden_4 = "City Escape - Hidden 4"
green_forest_5 = "Green Forest - 5" city_escape_hidden_5 = "City Escape - Hidden 5"
green_forest_upgrade = "Green Forest - Upgrade" city_escape_beetle = "City Escape - Gold Beetle"
pyramid_cave_1 = "Pyramid Cave - 1" city_escape_upgrade = "City Escape - Upgrade"
pyramid_cave_2 = "Pyramid Cave - 2" metal_harbor_1 = "Metal Harbor - 1"
pyramid_cave_3 = "Pyramid Cave - 3" metal_harbor_2 = "Metal Harbor - 2"
pyramid_cave_4 = "Pyramid Cave - 4" metal_harbor_3 = "Metal Harbor - 3"
pyramid_cave_5 = "Pyramid Cave - 5" metal_harbor_4 = "Metal Harbor - 4"
pyramid_cave_upgrade = "Pyramid Cave - Upgrade" metal_harbor_5 = "Metal Harbor - 5"
crazy_gadget_1 = "Crazy Gadget - 1" metal_harbor_chao_1 = "Metal Harbor - Chao Key 1"
crazy_gadget_2 = "Crazy Gadget - 2" metal_harbor_chao_2 = "Metal Harbor - Chao Key 2"
crazy_gadget_3 = "Crazy Gadget - 3" metal_harbor_chao_3 = "Metal Harbor - Chao Key 3"
crazy_gadget_4 = "Crazy Gadget - 4" metal_harbor_pipe_1 = "Metal Harbor - Pipe 1"
crazy_gadget_5 = "Crazy Gadget - 5" metal_harbor_beetle = "Metal Harbor - Gold Beetle"
crazy_gadget_upgrade = "Crazy Gadget - Upgrade" metal_harbor_upgrade = "Metal Harbor - Upgrade"
final_rush_1 = "Final Rush - 1" green_forest_1 = "Green Forest - 1"
final_rush_2 = "Final Rush - 2" green_forest_2 = "Green Forest - 2"
final_rush_3 = "Final Rush - 3" green_forest_3 = "Green Forest - 3"
final_rush_4 = "Final Rush - 4" green_forest_4 = "Green Forest - 4"
final_rush_5 = "Final Rush - 5" green_forest_5 = "Green Forest - 5"
final_rush_upgrade = "Final Rush - Upgrade" green_forest_chao_1 = "Green Forest - Chao Key 1"
green_forest_chao_2 = "Green Forest - Chao Key 2"
green_forest_chao_3 = "Green Forest - Chao Key 3"
green_forest_pipe_1 = "Green Forest - Pipe 1"
green_forest_pipe_2 = "Green Forest - Pipe 2"
green_forest_hidden_1 = "Green Forest - Hidden 1"
green_forest_hidden_2 = "Green Forest - Hidden 2"
green_forest_hidden_3 = "Green Forest - Hidden 3"
green_forest_hidden_4 = "Green Forest - Hidden 4"
green_forest_beetle = "Green Forest - Gold Beetle"
green_forest_upgrade = "Green Forest - Upgrade"
pyramid_cave_1 = "Pyramid Cave - 1"
pyramid_cave_2 = "Pyramid Cave - 2"
pyramid_cave_3 = "Pyramid Cave - 3"
pyramid_cave_4 = "Pyramid Cave - 4"
pyramid_cave_5 = "Pyramid Cave - 5"
pyramid_cave_chao_1 = "Pyramid Cave - Chao Key 1"
pyramid_cave_chao_2 = "Pyramid Cave - Chao Key 2"
pyramid_cave_chao_3 = "Pyramid Cave - Chao Key 3"
pyramid_cave_pipe_1 = "Pyramid Cave - Pipe 1"
pyramid_cave_pipe_2 = "Pyramid Cave - Pipe 2"
pyramid_cave_pipe_3 = "Pyramid Cave - Pipe 3"
pyramid_cave_pipe_4 = "Pyramid Cave - Pipe 4"
pyramid_cave_beetle = "Pyramid Cave - Gold Beetle"
pyramid_cave_upgrade = "Pyramid Cave - Upgrade"
crazy_gadget_1 = "Crazy Gadget - 1"
crazy_gadget_2 = "Crazy Gadget - 2"
crazy_gadget_3 = "Crazy Gadget - 3"
crazy_gadget_4 = "Crazy Gadget - 4"
crazy_gadget_5 = "Crazy Gadget - 5"
crazy_gadget_chao_1 = "Crazy Gadget - Chao Key 1"
crazy_gadget_chao_2 = "Crazy Gadget - Chao Key 2"
crazy_gadget_chao_3 = "Crazy Gadget - Chao Key 3"
crazy_gadget_pipe_1 = "Crazy Gadget - Pipe 1"
crazy_gadget_pipe_2 = "Crazy Gadget - Pipe 2"
crazy_gadget_pipe_3 = "Crazy Gadget - Pipe 3"
crazy_gadget_pipe_4 = "Crazy Gadget - Pipe 4"
crazy_gadget_hidden_1 = "Crazy Gadget - Hidden 1"
crazy_gadget_beetle = "Crazy Gadget - Gold Beetle"
crazy_gadget_upgrade = "Crazy Gadget - Upgrade"
final_rush_1 = "Final Rush - 1"
final_rush_2 = "Final Rush - 2"
final_rush_3 = "Final Rush - 3"
final_rush_4 = "Final Rush - 4"
final_rush_5 = "Final Rush - 5"
final_rush_chao_1 = "Final Rush - Chao Key 1"
final_rush_chao_2 = "Final Rush - Chao Key 2"
final_rush_chao_3 = "Final Rush - Chao Key 3"
final_rush_pipe_1 = "Final Rush - Pipe 1"
final_rush_pipe_2 = "Final Rush - Pipe 2"
final_rush_beetle = "Final Rush - Gold Beetle"
final_rush_upgrade = "Final Rush - Upgrade"
# Tails Mission Definitions # Tails Mission Definitions
prison_lane_1 = "Prison Lane - 1" prison_lane_1 = "Prison Lane - 1"
prison_lane_2 = "Prison Lane - 2" prison_lane_2 = "Prison Lane - 2"
prison_lane_3 = "Prison Lane - 3" prison_lane_3 = "Prison Lane - 3"
prison_lane_4 = "Prison Lane - 4" prison_lane_4 = "Prison Lane - 4"
prison_lane_5 = "Prison Lane - 5" prison_lane_5 = "Prison Lane - 5"
prison_lane_upgrade = "Prison Lane - Upgrade" prison_lane_chao_1 = "Prison Lane - Chao Key 1"
mission_street_1 = "Mission Street - 1" prison_lane_chao_2 = "Prison Lane - Chao Key 2"
mission_street_2 = "Mission Street - 2" prison_lane_chao_3 = "Prison Lane - Chao Key 3"
mission_street_3 = "Mission Street - 3" prison_lane_pipe_1 = "Prison Lane - Pipe 1"
mission_street_4 = "Mission Street - 4" prison_lane_pipe_2 = "Prison Lane - Pipe 2"
mission_street_5 = "Mission Street - 5" prison_lane_pipe_3 = "Prison Lane - Pipe 3"
mission_street_upgrade = "Mission Street - Upgrade" prison_lane_hidden_1 = "Prison Lane - Hidden 1"
route_101_1 = "Route 101 - 1" prison_lane_hidden_2 = "Prison Lane - Hidden 2"
route_101_2 = "Route 101 - 2" prison_lane_hidden_3 = "Prison Lane - Hidden 3"
route_101_3 = "Route 101 - 3" prison_lane_beetle = "Prison Lane - Gold Beetle"
route_101_4 = "Route 101 - 4" prison_lane_upgrade = "Prison Lane - Upgrade"
route_101_5 = "Route 101 - 5" mission_street_1 = "Mission Street - 1"
hidden_base_1 = "Hidden Base - 1" mission_street_2 = "Mission Street - 2"
hidden_base_2 = "Hidden Base - 2" mission_street_3 = "Mission Street - 3"
hidden_base_3 = "Hidden Base - 3" mission_street_4 = "Mission Street - 4"
hidden_base_4 = "Hidden Base - 4" mission_street_5 = "Mission Street - 5"
hidden_base_5 = "Hidden Base - 5" mission_street_chao_1 = "Mission Street - Chao Key 1"
hidden_base_upgrade = "Hidden Base - Upgrade" mission_street_chao_2 = "Mission Street - Chao Key 2"
eternal_engine_1 = "Eternal Engine - 1" mission_street_chao_3 = "Mission Street - Chao Key 3"
eternal_engine_2 = "Eternal Engine - 2" mission_street_pipe_1 = "Mission Street - Pipe 1"
eternal_engine_3 = "Eternal Engine - 3" mission_street_pipe_2 = "Mission Street - Pipe 2"
eternal_engine_4 = "Eternal Engine - 4" mission_street_pipe_3 = "Mission Street - Pipe 3"
eternal_engine_5 = "Eternal Engine - 5" mission_street_hidden_1 = "Mission Street - Hidden 1"
eternal_engine_upgrade = "Eternal Engine - Upgrade" mission_street_hidden_2 = "Mission Street - Hidden 2"
mission_street_hidden_3 = "Mission Street - Hidden 3"
mission_street_beetle = "Mission Street - Gold Beetle"
mission_street_upgrade = "Mission Street - Upgrade"
route_101_1 = "Route 101 - 1"
route_101_2 = "Route 101 - 2"
route_101_3 = "Route 101 - 3"
route_101_4 = "Route 101 - 4"
route_101_5 = "Route 101 - 5"
hidden_base_1 = "Hidden Base - 1"
hidden_base_2 = "Hidden Base - 2"
hidden_base_3 = "Hidden Base - 3"
hidden_base_4 = "Hidden Base - 4"
hidden_base_5 = "Hidden Base - 5"
hidden_base_chao_1 = "Hidden Base - Chao Key 1"
hidden_base_chao_2 = "Hidden Base - Chao Key 2"
hidden_base_pipe_1 = "Hidden Base - Pipe 1"
hidden_base_pipe_2 = "Hidden Base - Pipe 2"
hidden_base_pipe_3 = "Hidden Base - Pipe 3"
hidden_base_pipe_4 = "Hidden Base - Pipe 4"
hidden_base_pipe_5 = "Hidden Base - Pipe 5"
hidden_base_beetle = "Hidden Base - Gold Beetle"
hidden_base_upgrade = "Hidden Base - Upgrade"
eternal_engine_1 = "Eternal Engine - 1"
eternal_engine_2 = "Eternal Engine - 2"
eternal_engine_3 = "Eternal Engine - 3"
eternal_engine_4 = "Eternal Engine - 4"
eternal_engine_5 = "Eternal Engine - 5"
eternal_engine_chao_1 = "Eternal Engine - Chao Key 1"
eternal_engine_chao_2 = "Eternal Engine - Chao Key 2"
eternal_engine_chao_3 = "Eternal Engine - Chao Key 3"
eternal_engine_pipe_1 = "Eternal Engine - Pipe 1"
eternal_engine_pipe_2 = "Eternal Engine - Pipe 2"
eternal_engine_pipe_3 = "Eternal Engine - Pipe 3"
eternal_engine_pipe_4 = "Eternal Engine - Pipe 4"
eternal_engine_pipe_5 = "Eternal Engine - Pipe 5"
eternal_engine_beetle = "Eternal Engine - Gold Beetle"
eternal_engine_upgrade = "Eternal Engine - Upgrade"
# Knuckles Mission Definitions # Knuckles Mission Definitions
wild_canyon_1 = "Wild Canyon - 1" wild_canyon_1 = "Wild Canyon - 1"
wild_canyon_2 = "Wild Canyon - 2" wild_canyon_2 = "Wild Canyon - 2"
wild_canyon_3 = "Wild Canyon - 3" wild_canyon_3 = "Wild Canyon - 3"
wild_canyon_4 = "Wild Canyon - 4" wild_canyon_4 = "Wild Canyon - 4"
wild_canyon_5 = "Wild Canyon - 5" wild_canyon_5 = "Wild Canyon - 5"
wild_canyon_upgrade = "Wild Canyon - Upgrade" wild_canyon_chao_1 = "Wild Canyon - Chao Key 1"
pumpkin_hill_1 = "Pumpkin Hill - 1" wild_canyon_chao_2 = "Wild Canyon - Chao Key 2"
pumpkin_hill_2 = "Pumpkin Hill - 2" wild_canyon_chao_3 = "Wild Canyon - Chao Key 3"
pumpkin_hill_3 = "Pumpkin Hill - 3" wild_canyon_pipe_1 = "Wild Canyon - Pipe 1"
pumpkin_hill_4 = "Pumpkin Hill - 4" wild_canyon_pipe_2 = "Wild Canyon - Pipe 2"
pumpkin_hill_5 = "Pumpkin Hill - 5" wild_canyon_pipe_3 = "Wild Canyon - Pipe 3"
pumpkin_hill_upgrade = "Pumpkin Hill - Upgrade" wild_canyon_beetle = "Wild Canyon - Gold Beetle"
aquatic_mine_1 = "Aquatic Mine - 1" wild_canyon_upgrade = "Wild Canyon - Upgrade"
aquatic_mine_2 = "Aquatic Mine - 2" pumpkin_hill_1 = "Pumpkin Hill - 1"
aquatic_mine_3 = "Aquatic Mine - 3" pumpkin_hill_2 = "Pumpkin Hill - 2"
aquatic_mine_4 = "Aquatic Mine - 4" pumpkin_hill_3 = "Pumpkin Hill - 3"
aquatic_mine_5 = "Aquatic Mine - 5" pumpkin_hill_4 = "Pumpkin Hill - 4"
aquatic_mine_upgrade = "Aquatic Mine - Upgrade" pumpkin_hill_5 = "Pumpkin Hill - 5"
death_chamber_1 = "Death Chamber - 1" pumpkin_hill_chao_1 = "Pumpkin Hill - Chao Key 1"
death_chamber_2 = "Death Chamber - 2" pumpkin_hill_chao_2 = "Pumpkin Hill - Chao Key 2"
death_chamber_3 = "Death Chamber - 3" pumpkin_hill_chao_3 = "Pumpkin Hill - Chao Key 3"
death_chamber_4 = "Death Chamber - 4" pumpkin_hill_pipe_1 = "Pumpkin Hill - Pipe 1"
death_chamber_5 = "Death Chamber - 5" pumpkin_hill_hidden_1 = "Pumpkin Hill - Hidden 1"
death_chamber_upgrade = "Death Chamber - Upgrade" pumpkin_hill_upgrade = "Pumpkin Hill - Upgrade"
meteor_herd_1 = "Meteor Herd - 1" aquatic_mine_1 = "Aquatic Mine - 1"
meteor_herd_2 = "Meteor Herd - 2" aquatic_mine_2 = "Aquatic Mine - 2"
meteor_herd_3 = "Meteor Herd - 3" aquatic_mine_3 = "Aquatic Mine - 3"
meteor_herd_4 = "Meteor Herd - 4" aquatic_mine_4 = "Aquatic Mine - 4"
meteor_herd_5 = "Meteor Herd - 5" aquatic_mine_5 = "Aquatic Mine - 5"
meteor_herd_upgrade = "Meteor Herd - Upgrade" aquatic_mine_chao_1 = "Aquatic Mine - Chao Key 1"
aquatic_mine_chao_2 = "Aquatic Mine - Chao Key 2"
aquatic_mine_chao_3 = "Aquatic Mine - Chao Key 3"
aquatic_mine_pipe_1 = "Aquatic Mine - Pipe 1"
aquatic_mine_pipe_2 = "Aquatic Mine - Pipe 2"
aquatic_mine_pipe_3 = "Aquatic Mine - Pipe 3"
aquatic_mine_beetle = "Aquatic Mine - Gold Beetle"
aquatic_mine_upgrade = "Aquatic Mine - Upgrade"
death_chamber_1 = "Death Chamber - 1"
death_chamber_2 = "Death Chamber - 2"
death_chamber_3 = "Death Chamber - 3"
death_chamber_4 = "Death Chamber - 4"
death_chamber_5 = "Death Chamber - 5"
death_chamber_chao_1 = "Death Chamber - Chao Key 1"
death_chamber_chao_2 = "Death Chamber - Chao Key 2"
death_chamber_chao_3 = "Death Chamber - Chao Key 3"
death_chamber_pipe_1 = "Death Chamber - Pipe 1"
death_chamber_pipe_2 = "Death Chamber - Pipe 2"
death_chamber_pipe_3 = "Death Chamber - Pipe 3"
death_chamber_hidden_1 = "Death Chamber - Hidden 1"
death_chamber_hidden_2 = "Death Chamber - Hidden 2"
death_chamber_beetle = "Death Chamber - Gold Beetle"
death_chamber_upgrade = "Death Chamber - Upgrade"
meteor_herd_1 = "Meteor Herd - 1"
meteor_herd_2 = "Meteor Herd - 2"
meteor_herd_3 = "Meteor Herd - 3"
meteor_herd_4 = "Meteor Herd - 4"
meteor_herd_5 = "Meteor Herd - 5"
meteor_herd_chao_1 = "Meteor Herd - Chao Key 1"
meteor_herd_chao_2 = "Meteor Herd - Chao Key 2"
meteor_herd_chao_3 = "Meteor Herd - Chao Key 3"
meteor_herd_pipe_1 = "Meteor Herd - Pipe 1"
meteor_herd_pipe_2 = "Meteor Herd - Pipe 2"
meteor_herd_pipe_3 = "Meteor Herd - Pipe 3"
meteor_herd_beetle = "Meteor Herd - Gold Beetle"
meteor_herd_upgrade = "Meteor Herd - Upgrade"
# Shadow Mission Definitions # Shadow Mission Definitions
radical_highway_1 = "Radical Highway - 1" radical_highway_1 = "Radical Highway - 1"
radical_highway_2 = "Radical Highway - 2" radical_highway_2 = "Radical Highway - 2"
radical_highway_3 = "Radical Highway - 3" radical_highway_3 = "Radical Highway - 3"
radical_highway_4 = "Radical Highway - 4" radical_highway_4 = "Radical Highway - 4"
radical_highway_5 = "Radical Highway - 5" radical_highway_5 = "Radical Highway - 5"
radical_highway_upgrade = "Radical Highway - Upgrade" radical_highway_chao_1 = "Radical Highway - Chao Key 1"
white_jungle_1 = "White Jungle - 1" radical_highway_chao_2 = "Radical Highway - Chao Key 2"
white_jungle_2 = "White Jungle - 2" radical_highway_chao_3 = "Radical Highway - Chao Key 3"
white_jungle_3 = "White Jungle - 3" radical_highway_pipe_1 = "Radical Highway - Pipe 1"
white_jungle_4 = "White Jungle - 4" radical_highway_pipe_2 = "Radical Highway - Pipe 2"
white_jungle_5 = "White Jungle - 5" radical_highway_pipe_3 = "Radical Highway - Pipe 3"
white_jungle_upgrade = "White Jungle - Upgrade" radical_highway_hidden_1 = "Radical Highway - Hidden 1"
sky_rail_1 = "Sky Rail - 1" radical_highway_hidden_2 = "Radical Highway - Hidden 2"
sky_rail_2 = "Sky Rail - 2" radical_highway_hidden_3 = "Radical Highway - Hidden 3"
sky_rail_3 = "Sky Rail - 3" radical_highway_beetle = "Radical Highway - Gold Beetle"
sky_rail_4 = "Sky Rail - 4" radical_highway_upgrade = "Radical Highway - Upgrade"
sky_rail_5 = "Sky Rail - 5" white_jungle_1 = "White Jungle - 1"
sky_rail_upgrade = "Sky Rail - Upgrade" white_jungle_2 = "White Jungle - 2"
final_chase_1 = "Final Chase - 1" white_jungle_3 = "White Jungle - 3"
final_chase_2 = "Final Chase - 2" white_jungle_4 = "White Jungle - 4"
final_chase_3 = "Final Chase - 3" white_jungle_5 = "White Jungle - 5"
final_chase_4 = "Final Chase - 4" white_jungle_chao_1 = "White Jungle - Chao Key 1"
final_chase_5 = "Final Chase - 5" white_jungle_chao_2 = "White Jungle - Chao Key 2"
final_chase_upgrade = "Final Chase - Upgrade" white_jungle_chao_3 = "White Jungle - Chao Key 3"
white_jungle_pipe_1 = "White Jungle - Pipe 1"
white_jungle_pipe_2 = "White Jungle - Pipe 2"
white_jungle_pipe_3 = "White Jungle - Pipe 3"
white_jungle_pipe_4 = "White Jungle - Pipe 4"
white_jungle_hidden_1 = "White Jungle - Hidden 1"
white_jungle_hidden_2 = "White Jungle - Hidden 2"
white_jungle_hidden_3 = "White Jungle - Hidden 3"
white_jungle_beetle = "White Jungle - Gold Beetle"
white_jungle_upgrade = "White Jungle - Upgrade"
sky_rail_1 = "Sky Rail - 1"
sky_rail_2 = "Sky Rail - 2"
sky_rail_3 = "Sky Rail - 3"
sky_rail_4 = "Sky Rail - 4"
sky_rail_5 = "Sky Rail - 5"
sky_rail_chao_1 = "Sky Rail - Chao Key 1"
sky_rail_chao_2 = "Sky Rail - Chao Key 2"
sky_rail_chao_3 = "Sky Rail - Chao Key 3"
sky_rail_pipe_1 = "Sky Rail - Pipe 1"
sky_rail_pipe_2 = "Sky Rail - Pipe 2"
sky_rail_pipe_3 = "Sky Rail - Pipe 3"
sky_rail_pipe_4 = "Sky Rail - Pipe 4"
sky_rail_pipe_5 = "Sky Rail - Pipe 5"
sky_rail_pipe_6 = "Sky Rail - Pipe 6"
sky_rail_beetle = "Sky Rail - Gold Beetle"
sky_rail_upgrade = "Sky Rail - Upgrade"
final_chase_1 = "Final Chase - 1"
final_chase_2 = "Final Chase - 2"
final_chase_3 = "Final Chase - 3"
final_chase_4 = "Final Chase - 4"
final_chase_5 = "Final Chase - 5"
final_chase_chao_1 = "Final Chase - Chao Key 1"
final_chase_chao_2 = "Final Chase - Chao Key 2"
final_chase_chao_3 = "Final Chase - Chao Key 3"
final_chase_pipe_1 = "Final Chase - Pipe 1"
final_chase_pipe_2 = "Final Chase - Pipe 2"
final_chase_pipe_3 = "Final Chase - Pipe 3"
final_chase_beetle = "Final Chase - Gold Beetle"
final_chase_upgrade = "Final Chase - Upgrade"
# Eggman Mission Definitions # Eggman Mission Definitions
iron_gate_1 = "Iron Gate - 1" iron_gate_1 = "Iron Gate - 1"
iron_gate_2 = "Iron Gate - 2" iron_gate_2 = "Iron Gate - 2"
iron_gate_3 = "Iron Gate - 3" iron_gate_3 = "Iron Gate - 3"
iron_gate_4 = "Iron Gate - 4" iron_gate_4 = "Iron Gate - 4"
iron_gate_5 = "Iron Gate - 5" iron_gate_5 = "Iron Gate - 5"
iron_gate_upgrade = "Iron Gate - Upgrade" iron_gate_chao_1 = "Iron Gate - Chao Key 1"
sand_ocean_1 = "Sand Ocean - 1" iron_gate_chao_2 = "Iron Gate - Chao Key 2"
sand_ocean_2 = "Sand Ocean - 2" iron_gate_chao_3 = "Iron Gate - Chao Key 3"
sand_ocean_3 = "Sand Ocean - 3" iron_gate_pipe_1 = "Iron Gate - Pipe 1"
sand_ocean_4 = "Sand Ocean - 4" iron_gate_pipe_2 = "Iron Gate - Pipe 2"
sand_ocean_5 = "Sand Ocean - 5" iron_gate_pipe_3 = "Iron Gate - Pipe 3"
sand_ocean_upgrade = "Sand Ocean - Upgrade" iron_gate_pipe_4 = "Iron Gate - Pipe 4"
lost_colony_1 = "Lost Colony - 1" iron_gate_pipe_5 = "Iron Gate - Pipe 5"
lost_colony_2 = "Lost Colony - 2" iron_gate_beetle = "Iron Gate - Gold Beetle"
lost_colony_3 = "Lost Colony - 3" iron_gate_upgrade = "Iron Gate - Upgrade"
lost_colony_4 = "Lost Colony - 4" sand_ocean_1 = "Sand Ocean - 1"
lost_colony_5 = "Lost Colony - 5" sand_ocean_2 = "Sand Ocean - 2"
lost_colony_upgrade = "Lost Colony - Upgrade" sand_ocean_3 = "Sand Ocean - 3"
weapons_bed_1 = "Weapons Bed - 1" sand_ocean_4 = "Sand Ocean - 4"
weapons_bed_2 = "Weapons Bed - 2" sand_ocean_5 = "Sand Ocean - 5"
weapons_bed_3 = "Weapons Bed - 3" sand_ocean_chao_1 = "Sand Ocean - Chao Key 1"
weapons_bed_4 = "Weapons Bed - 4" sand_ocean_chao_2 = "Sand Ocean - Chao Key 2"
weapons_bed_5 = "Weapons Bed - 5" sand_ocean_chao_3 = "Sand Ocean - Chao Key 3"
weapons_bed_upgrade = "Weapons Bed - Upgrade" sand_ocean_pipe_1 = "Sand Ocean - Pipe 1"
cosmic_wall_1 = "Cosmic Wall - 1" sand_ocean_pipe_2 = "Sand Ocean - Pipe 2"
cosmic_wall_2 = "Cosmic Wall - 2" sand_ocean_pipe_3 = "Sand Ocean - Pipe 3"
cosmic_wall_3 = "Cosmic Wall - 3" sand_ocean_pipe_4 = "Sand Ocean - Pipe 4"
cosmic_wall_4 = "Cosmic Wall - 4" sand_ocean_pipe_5 = "Sand Ocean - Pipe 5"
cosmic_wall_5 = "Cosmic Wall - 5" sand_ocean_beetle = "Sand Ocean - Gold Beetle"
cosmic_wall_upgrade = "Cosmic Wall - Upgrade" sand_ocean_upgrade = "Sand Ocean - Upgrade"
lost_colony_1 = "Lost Colony - 1"
lost_colony_2 = "Lost Colony - 2"
lost_colony_3 = "Lost Colony - 3"
lost_colony_4 = "Lost Colony - 4"
lost_colony_5 = "Lost Colony - 5"
lost_colony_chao_1 = "Lost Colony - Chao Key 1"
lost_colony_chao_2 = "Lost Colony - Chao Key 2"
lost_colony_chao_3 = "Lost Colony - Chao Key 3"
lost_colony_pipe_1 = "Lost Colony - Pipe 1"
lost_colony_pipe_2 = "Lost Colony - Pipe 2"
lost_colony_hidden_1 = "Lost Colony - Hidden 1"
lost_colony_beetle = "Lost Colony - Gold Beetle"
lost_colony_upgrade = "Lost Colony - Upgrade"
weapons_bed_1 = "Weapons Bed - 1"
weapons_bed_2 = "Weapons Bed - 2"
weapons_bed_3 = "Weapons Bed - 3"
weapons_bed_4 = "Weapons Bed - 4"
weapons_bed_5 = "Weapons Bed - 5"
weapons_bed_chao_1 = "Weapons Bed - Chao Key 1"
weapons_bed_chao_2 = "Weapons Bed - Chao Key 2"
weapons_bed_chao_3 = "Weapons Bed - Chao Key 3"
weapons_bed_pipe_1 = "Weapons Bed - Pipe 1"
weapons_bed_pipe_2 = "Weapons Bed - Pipe 2"
weapons_bed_pipe_3 = "Weapons Bed - Pipe 3"
weapons_bed_pipe_4 = "Weapons Bed - Pipe 4"
weapons_bed_pipe_5 = "Weapons Bed - Pipe 5"
weapons_bed_upgrade = "Weapons Bed - Upgrade"
cosmic_wall_1 = "Cosmic Wall - 1"
cosmic_wall_2 = "Cosmic Wall - 2"
cosmic_wall_3 = "Cosmic Wall - 3"
cosmic_wall_4 = "Cosmic Wall - 4"
cosmic_wall_5 = "Cosmic Wall - 5"
cosmic_wall_chao_1 = "Cosmic Wall - Chao Key 1"
cosmic_wall_chao_2 = "Cosmic Wall - Chao Key 2"
cosmic_wall_chao_3 = "Cosmic Wall - Chao Key 3"
cosmic_wall_pipe_1 = "Cosmic Wall - Pipe 1"
cosmic_wall_pipe_2 = "Cosmic Wall - Pipe 2"
cosmic_wall_pipe_3 = "Cosmic Wall - Pipe 3"
cosmic_wall_pipe_4 = "Cosmic Wall - Pipe 4"
cosmic_wall_pipe_5 = "Cosmic Wall - Pipe 5"
cosmic_wall_beetle = "Cosmic Wall - Gold Beetle"
cosmic_wall_upgrade = "Cosmic Wall - Upgrade"
# Rouge Mission Definitions # Rouge Mission Definitions
dry_lagoon_1 = "Dry Lagoon - 1" dry_lagoon_1 = "Dry Lagoon - 1"
dry_lagoon_2 = "Dry Lagoon - 2" dry_lagoon_2 = "Dry Lagoon - 2"
dry_lagoon_3 = "Dry Lagoon - 3" dry_lagoon_3 = "Dry Lagoon - 3"
dry_lagoon_4 = "Dry Lagoon - 4" dry_lagoon_4 = "Dry Lagoon - 4"
dry_lagoon_5 = "Dry Lagoon - 5" dry_lagoon_5 = "Dry Lagoon - 5"
dry_lagoon_upgrade = "Dry Lagoon - Upgrade" dry_lagoon_chao_1 = "Dry Lagoon - Chao Key 1"
egg_quarters_1 = "Egg Quarters - 1" dry_lagoon_chao_2 = "Dry Lagoon - Chao Key 2"
egg_quarters_2 = "Egg Quarters - 2" dry_lagoon_chao_3 = "Dry Lagoon - Chao Key 3"
egg_quarters_3 = "Egg Quarters - 3" dry_lagoon_pipe_1 = "Dry Lagoon - Pipe 1"
egg_quarters_4 = "Egg Quarters - 4" dry_lagoon_hidden_1 = "Dry Lagoon - Hidden 1"
egg_quarters_5 = "Egg Quarters - 5" dry_lagoon_beetle = "Dry Lagoon - Gold Beetle"
egg_quarters_upgrade = "Egg Quarters - Upgrade" dry_lagoon_upgrade = "Dry Lagoon - Upgrade"
security_hall_1 = "Security Hall - 1" egg_quarters_1 = "Egg Quarters - 1"
security_hall_2 = "Security Hall - 2" egg_quarters_2 = "Egg Quarters - 2"
security_hall_3 = "Security Hall - 3" egg_quarters_3 = "Egg Quarters - 3"
security_hall_4 = "Security Hall - 4" egg_quarters_4 = "Egg Quarters - 4"
security_hall_5 = "Security Hall - 5" egg_quarters_5 = "Egg Quarters - 5"
security_hall_upgrade = "Security Hall - Upgrade" egg_quarters_chao_1 = "Egg Quarters - Chao Key 1"
route_280_1 = "Route 280 - 1" egg_quarters_chao_2 = "Egg Quarters - Chao Key 2"
route_280_2 = "Route 280 - 2" egg_quarters_chao_3 = "Egg Quarters - Chao Key 3"
route_280_3 = "Route 280 - 3" egg_quarters_pipe_1 = "Egg Quarters - Pipe 1"
route_280_4 = "Route 280 - 4" egg_quarters_pipe_2 = "Egg Quarters - Pipe 2"
route_280_5 = "Route 280 - 5" egg_quarters_hidden_1 = "Egg Quarters - Hidden 1"
mad_space_1 = "Mad Space - 1" egg_quarters_hidden_2 = "Egg Quarters - Hidden 2"
mad_space_2 = "Mad Space - 2" egg_quarters_beetle = "Egg Quarters - Gold Beetle"
mad_space_3 = "Mad Space - 3" egg_quarters_upgrade = "Egg Quarters - Upgrade"
mad_space_4 = "Mad Space - 4" security_hall_1 = "Security Hall - 1"
mad_space_5 = "Mad Space - 5" security_hall_2 = "Security Hall - 2"
mad_space_upgrade = "Mad Space - Upgrade" security_hall_3 = "Security Hall - 3"
security_hall_4 = "Security Hall - 4"
security_hall_5 = "Security Hall - 5"
security_hall_chao_1 = "Security Hall - Chao Key 1"
security_hall_chao_2 = "Security Hall - Chao Key 2"
security_hall_chao_3 = "Security Hall - Chao Key 3"
security_hall_pipe_1 = "Security Hall - Pipe 1"
security_hall_hidden_1 = "Security Hall - Hidden 1"
security_hall_beetle = "Security Hall - Gold Beetle"
security_hall_upgrade = "Security Hall - Upgrade"
route_280_1 = "Route 280 - 1"
route_280_2 = "Route 280 - 2"
route_280_3 = "Route 280 - 3"
route_280_4 = "Route 280 - 4"
route_280_5 = "Route 280 - 5"
mad_space_1 = "Mad Space - 1"
mad_space_2 = "Mad Space - 2"
mad_space_3 = "Mad Space - 3"
mad_space_4 = "Mad Space - 4"
mad_space_5 = "Mad Space - 5"
mad_space_chao_1 = "Mad Space - Chao Key 1"
mad_space_chao_2 = "Mad Space - Chao Key 2"
mad_space_chao_3 = "Mad Space - Chao Key 3"
mad_space_pipe_1 = "Mad Space - Pipe 1"
mad_space_pipe_2 = "Mad Space - Pipe 2"
mad_space_pipe_3 = "Mad Space - Pipe 3"
mad_space_pipe_4 = "Mad Space - Pipe 4"
mad_space_beetle = "Mad Space - Gold Beetle"
mad_space_upgrade = "Mad Space - Upgrade"
# Final Mission Definitions # Final Mission Definitions
cannon_core_1 = "Cannon Core - 1" cannon_core_1 = "Cannon Core - 1"
cannon_core_2 = "Cannon Core - 2" cannon_core_2 = "Cannon Core - 2"
cannon_core_3 = "Cannon Core - 3" cannon_core_3 = "Cannon Core - 3"
cannon_core_4 = "Cannon Core - 4" cannon_core_4 = "Cannon Core - 4"
cannon_core_5 = "Cannon Core - 5" cannon_core_5 = "Cannon Core - 5"
cannon_core_chao_1 = "Cannon Core - Chao Key 1"
cannon_core_chao_2 = "Cannon Core - Chao Key 2"
cannon_core_chao_3 = "Cannon Core - Chao Key 3"
cannon_core_pipe_1 = "Cannon Core - Pipe 1"
cannon_core_pipe_2 = "Cannon Core - Pipe 2"
cannon_core_pipe_3 = "Cannon Core - Pipe 3"
cannon_core_pipe_4 = "Cannon Core - Pipe 4"
cannon_core_pipe_5 = "Cannon Core - Pipe 5"
cannon_core_hidden_1 = "Cannon Core - Hidden 1"
cannon_core_beetle = "Cannon Core - Gold Beetle"
# Boss Definitions # Boss Definitions
gate_1_boss = "Gate 1 Boss" gate_1_boss = "Gate 1 Boss"
@ -277,8 +518,10 @@ chao_expert_karate = "Chao Karate - Expert"
chao_super_karate = "Chao Karate - Super" chao_super_karate = "Chao Karate - Super"
# Other Definitions # Other Definitions
green_hill = "Green Hill" green_hill = "Green Hill"
biolizard = "Biolizard" green_hill_chao_1 = "Green Hill - Chao Key 1"
biolizard = "Biolizard"
finalhazard = "Finalhazard"
# Region Definitions # Region Definitions
@ -336,6 +579,8 @@ cannon_core_region = "Cannon Core"
biolizard_region = "Biolizard" biolizard_region = "Biolizard"
green_hill_region = "Green Hill"
chao_garden_beginner_region = "Chao Garden - Beginner" chao_garden_beginner_region = "Chao Garden - Beginner"
chao_garden_intermediate_region = "Chao Garden - Intermediate" chao_garden_intermediate_region = "Chao Garden - Intermediate"
chao_garden_expert_region = "Chao Garden - Expert" chao_garden_expert_region = "Chao Garden - Expert"

View File

@ -3,6 +3,27 @@ import typing
from Options import Choice, Range, Option, Toggle, DeathLink, DefaultOnToggle, OptionList from Options import Choice, Range, Option, Toggle, DeathLink, DefaultOnToggle, OptionList
class Goal(Choice):
"""
Determines the goal of the seed
Biolizard: Finish Cannon's Core and defeat the Biolizard and Finalhazard
Chaos Emerald Hunt: Find the Seven Chaos Emeralds and reach Green Hill Zone
Finalhazard Chaos Emerald Hunt: Find the Seven Chaos Emeralds and reach Green Hill Zone, then defeat Finalhazard
"""
display_name = "Goal"
option_biolizard = 0
option_chaos_emerald_hunt = 1
option_finalhazard_chaos_emerald_hunt = 2
default = 0
class MissionShuffle(Toggle):
"""
Determines whether missions order will be shuffled per level
"""
display_name = "Mission Shuffle"
class BaseTrapWeight(Choice): class BaseTrapWeight(Choice):
""" """
Base Class for Trap Weights Base Class for Trap Weights
@ -42,6 +63,27 @@ class TinyTrapWeight(BaseTrapWeight):
display_name = "Tiny Trap Weight" display_name = "Tiny Trap Weight"
class GravityTrapWeight(BaseTrapWeight):
"""
Likelihood of a receiving a trap which increases gravity
"""
display_name = "Gravity Trap Weight"
class ExpositionTrapWeight(BaseTrapWeight):
"""
Likelihood of a receiving a trap which tells you the story
"""
display_name = "Exposition Trap Weight"
class DarknessTrapWeight(BaseTrapWeight):
"""
Likelihood of a receiving a trap which makes the world dark
"""
display_name = "Darkness Trap Weight"
class JunkFillPercentage(Range): class JunkFillPercentage(Range):
""" """
Replace a percentage of non-required emblems in the item pool with random junk items Replace a percentage of non-required emblems in the item pool with random junk items
@ -78,11 +120,41 @@ class IncludeMissions(Range):
default = 2 default = 2
class Keysanity(Toggle):
"""
Determines whether picking up Chao Keys grants checks
"""
display_name = "Keysanity"
class Whistlesanity(Choice):
"""
Determines whether whistling at various spots grants checks
None: No Whistle Spots grant checks
Pipes: Whistling at Pipes grants checks
Hidden: Whistling at Hidden Whistle Spots grants checks
Both: Whistling at both Pipes and Hidden Whistle Spots grants checks
"""
display_name = "Whistlesanity"
option_none = 0
option_pipes = 1
option_hidden = 2
option_both = 3
default = 0
class Beetlesanity(Toggle):
"""
Determines whether destroying Gold Beetles grants checks
"""
display_name = "Beetlesanity"
class EmblemPercentageForCannonsCore(Range): class EmblemPercentageForCannonsCore(Range):
""" """
Allows logic to gate the final mission behind a number of Emblems Allows logic to gate the final mission behind a number of Emblems
""" """
display_name = "Emblem Percentage for Cannons Core" display_name = "Emblem Percentage for Cannon's Core"
range_start = 0 range_start = 0
range_end = 75 range_end = 75
default = 50 default = 50
@ -172,24 +244,280 @@ class ChaoRaceChecks(Choice):
default = 0 default = 0
class RequiredCannonsCoreMissions(Choice):
"""
Determines how many Cannon's Core missions must be completed to unlock the Biolizard (for the "Biolizard" goal)
First: Only the first mission must be completed
All Active: All active Cannon's Core missions must be completed
"""
display_name = "Required Cannon's Core Missions"
option_first = 0
option_all_active = 1
default = 0
class BaseMissionCount(Range):
"""
Base class for mission count options
"""
range_start = 1
range_end = 5
default = 2
class SpeedMissionCount(BaseMissionCount):
"""
The number of active missions to include for Sonic and Shadow stages
"""
display_name = "Speed Mission Count"
class SpeedMission2(DefaultOnToggle):
"""
Determines if the Sonic and Shadow 100 rings missions should be included
"""
display_name = "Speed Mission 2"
class SpeedMission3(DefaultOnToggle):
"""
Determines if the Sonic and Shadow lost chao missions should be included
"""
display_name = "Speed Mission 3"
class SpeedMission4(DefaultOnToggle):
"""
Determines if the Sonic and Shadow time trial missions should be included
"""
display_name = "Speed Mission 4"
class SpeedMission5(DefaultOnToggle):
"""
Determines if the Sonic and Shadow hard missions should be included
"""
display_name = "Speed Mission 5"
class MechMissionCount(BaseMissionCount):
"""
The number of active missions to include for Tails and Eggman stages
"""
display_name = "Mech Mission Count"
class MechMission2(DefaultOnToggle):
"""
Determines if the Tails and Eggman 100 rings missions should be included
"""
display_name = "Mech Mission 2"
class MechMission3(DefaultOnToggle):
"""
Determines if the Tails and Eggman lost chao missions should be included
"""
display_name = "Mech Mission 3"
class MechMission4(DefaultOnToggle):
"""
Determines if the Tails and Eggman time trial missions should be included
"""
display_name = "Mech Mission 4"
class MechMission5(DefaultOnToggle):
"""
Determines if the Tails and Eggman hard missions should be included
"""
display_name = "Mech Mission 5"
class HuntMissionCount(BaseMissionCount):
"""
The number of active missions to include for Knuckles and Rouge stages
"""
display_name = "Hunt Mission Count"
class HuntMission2(DefaultOnToggle):
"""
Determines if the Knuckles and Rouge 100 rings missions should be included
"""
display_name = "Hunt Mission 2"
class HuntMission3(DefaultOnToggle):
"""
Determines if the Knuckles and Rouge lost chao missions should be included
"""
display_name = "Hunt Mission 3"
class HuntMission4(DefaultOnToggle):
"""
Determines if the Knuckles and Rouge time trial missions should be included
"""
display_name = "Hunt Mission 4"
class HuntMission5(DefaultOnToggle):
"""
Determines if the Knuckles and Rouge hard missions should be included
"""
display_name = "Hunt Mission 5"
class KartMissionCount(BaseMissionCount):
"""
The number of active missions to include for Route 101 and 280
"""
display_name = "Kart Mission Count"
class KartMission2(DefaultOnToggle):
"""
Determines if the Route 101 and 280 100 rings missions should be included
"""
display_name = "Kart Mission 2"
class KartMission3(DefaultOnToggle):
"""
Determines if the Route 101 and 280 avoid cars missions should be included
"""
display_name = "Kart Mission 3"
class KartMission4(DefaultOnToggle):
"""
Determines if the Route 101 and 280 avoid walls missions should be included
"""
display_name = "Kart Mission 4"
class KartMission5(DefaultOnToggle):
"""
Determines if the Route 101 and 280 hard missions should be included
"""
display_name = "Kart Mission 5"
class CannonsCoreMissionCount(BaseMissionCount):
"""
The number of active missions to include for Cannon's Core
"""
display_name = "Cannon's Core Mission Count"
class CannonsCoreMission2(DefaultOnToggle):
"""
Determines if the Cannon's Core 100 rings mission should be included
"""
display_name = "Cannon's Core Mission 2"
class CannonsCoreMission3(DefaultOnToggle):
"""
Determines if the Cannon's Core lost chao mission should be included
"""
display_name = "Cannon's Core Mission 3"
class CannonsCoreMission4(DefaultOnToggle):
"""
Determines if the Cannon's Core time trial mission should be included
"""
display_name = "Cannon's Core Mission 4"
class CannonsCoreMission5(DefaultOnToggle):
"""
Determines if the Cannon's Core hard mission should be included
"""
display_name = "Cannon's Core Mission 5"
class SADXMusic(Choice):
"""
Whether the randomizer will include Sonic Adventure DX Music in the music pool
SA2B: Only SA2B music will be played
SADX: Only SADX music will be played
Both: Both SA2B and SADX music will be played
NOTE: This option requires the player to own a PC copy of SADX and to follow the addition steps in the setup guide.
"""
display_name = "SADX Music"
option_sa2b = 0
option_sadx = 1
option_both = 2
default = 0
@classmethod
def get_option_name(cls, value) -> str:
if cls.auto_display_name and value != 2:
return cls.name_lookup[value].upper()
else:
return cls.name_lookup[value]
class MusicShuffle(Choice): class MusicShuffle(Choice):
""" """
What type of Music Shuffle is used What type of Music Shuffle is used
Off: No music is shuffled. Off: No music is shuffled.
Levels: Level music is shuffled. Levels: Level music is shuffled.
Full: Level, Menu, and Additional music is shuffled. Full: Level, Menu, and Additional music is shuffled.
Singularity: Level, Menu, and Additional music is all replaced with a single random song.
""" """
display_name = "Music Shuffle Type" display_name = "Music Shuffle Type"
option_none = 0 option_none = 0
option_levels = 1 option_levels = 1
option_full = 2 option_full = 2
option_singularity = 3
default = 0
class Narrator(Choice):
"""
Which menu narrator is used
"""
display_name = "Narrator"
option_default = 0
option_shadow = 1
option_rouge = 2
option_eggman = 3
option_maria = 4
option_secretary = 5
option_omochao = 6
option_amy = 7
option_tails = 8
option_knuckles = 9
option_sonic = 10
default = 0
class LogicDifficulty(Choice):
"""
What set of Upgrade Requirement logic to use
Standard: The logic assumes the "intended" usage of Upgrades to progress through levels
Hard: Some simple skips or sequence breaks may be required
"""
display_name = "Logic Difficulty"
option_standard = 0
option_hard = 1
default = 0 default = 0
sa2b_options: typing.Dict[str, type(Option)] = { sa2b_options: typing.Dict[str, type(Option)] = {
"include_missions": IncludeMissions, "goal": Goal,
"mission_shuffle": MissionShuffle,
"keysanity": Keysanity,
"whistlesanity": Whistlesanity,
"beetlesanity": Beetlesanity,
"required_rank": RequiredRank, "required_rank": RequiredRank,
"emblem_percentage_for_cannons_core": EmblemPercentageForCannonsCore, "emblem_percentage_for_cannons_core": EmblemPercentageForCannonsCore,
"required_cannons_core_missions": RequiredCannonsCoreMissions,
"number_of_level_gates": NumberOfLevelGates, "number_of_level_gates": NumberOfLevelGates,
"level_gate_distribution": LevelGateDistribution, "level_gate_distribution": LevelGateDistribution,
"level_gate_costs": LevelGateCosts, "level_gate_costs": LevelGateCosts,
@ -202,6 +530,37 @@ sa2b_options: typing.Dict[str, type(Option)] = {
"timestop_trap_weight": TimestopTrapWeight, "timestop_trap_weight": TimestopTrapWeight,
"confusion_trap_weight": ConfusionTrapWeight, "confusion_trap_weight": ConfusionTrapWeight,
"tiny_trap_weight": TinyTrapWeight, "tiny_trap_weight": TinyTrapWeight,
"gravity_trap_weight": GravityTrapWeight,
"exposition_trap_weight": ExpositionTrapWeight,
#"darkness_trap_weight": DarknessTrapWeight,
"sadx_music": SADXMusic,
"music_shuffle": MusicShuffle, "music_shuffle": MusicShuffle,
"narrator": Narrator,
"logic_difficulty": LogicDifficulty,
"speed_mission_count": SpeedMissionCount,
"speed_mission_2": SpeedMission2,
"speed_mission_3": SpeedMission3,
"speed_mission_4": SpeedMission4,
"speed_mission_5": SpeedMission5,
"mech_mission_count": MechMissionCount,
"mech_mission_2": MechMission2,
"mech_mission_3": MechMission3,
"mech_mission_4": MechMission4,
"mech_mission_5": MechMission5,
"hunt_mission_count": HuntMissionCount,
"hunt_mission_2": HuntMission2,
"hunt_mission_3": HuntMission3,
"hunt_mission_4": HuntMission4,
"hunt_mission_5": HuntMission5,
"kart_mission_count": KartMissionCount,
"kart_mission_2": KartMission2,
"kart_mission_3": KartMission3,
"kart_mission_4": KartMission4,
"kart_mission_5": KartMission5,
"cannons_core_mission_count": CannonsCoreMissionCount,
"cannons_core_mission_2": CannonsCoreMission2,
"cannons_core_mission_3": CannonsCoreMission3,
"cannons_core_mission_4": CannonsCoreMission4,
"cannons_core_mission_5": CannonsCoreMission5,
"death_link": DeathLink, "death_link": DeathLink,
} }

View File

@ -87,18 +87,34 @@ gate_0_whitelist_regions = [
def create_regions(world, player: int, active_locations): def create_regions(world, player: int, active_locations):
menu_region = create_region(world, player, active_locations, 'Menu', None, None) menu_region = create_region(world, player, active_locations, 'Menu', None)
gate_0_region = create_region(world, player, active_locations, 'Gate 0', None, None)
gate_1_region = create_region(world, player, active_locations, 'Gate 1', None, None) gate_0_region = create_region(world, player, active_locations, 'Gate 0', None)
gate_2_region = create_region(world, player, active_locations, 'Gate 2', None, None)
gate_3_region = create_region(world, player, active_locations, 'Gate 3', None, None) if world.number_of_level_gates[player].value >= 1:
gate_4_region = create_region(world, player, active_locations, 'Gate 4', None, None) gate_1_boss_region = create_region(world, player, active_locations, 'Gate 1 Boss', [LocationName.gate_1_boss])
gate_5_region = create_region(world, player, active_locations, 'Gate 5', None, None) gate_1_region = create_region(world, player, active_locations, 'Gate 1', None)
gate_1_boss_region = create_region(world, player, active_locations, 'Gate 1 Boss', [LocationName.gate_1_boss], None) world.regions += [gate_1_region, gate_1_boss_region]
gate_2_boss_region = create_region(world, player, active_locations, 'Gate 2 Boss', [LocationName.gate_2_boss], None)
gate_3_boss_region = create_region(world, player, active_locations, 'Gate 3 Boss', [LocationName.gate_3_boss], None) if world.number_of_level_gates[player].value >= 2:
gate_4_boss_region = create_region(world, player, active_locations, 'Gate 4 Boss', [LocationName.gate_4_boss], None) gate_2_boss_region = create_region(world, player, active_locations, 'Gate 2 Boss', [LocationName.gate_2_boss])
gate_5_boss_region = create_region(world, player, active_locations, 'Gate 5 Boss', [LocationName.gate_5_boss], None) gate_2_region = create_region(world, player, active_locations, 'Gate 2', None)
world.regions += [gate_2_region, gate_2_boss_region]
if world.number_of_level_gates[player].value >= 3:
gate_3_boss_region = create_region(world, player, active_locations, 'Gate 3 Boss', [LocationName.gate_3_boss])
gate_3_region = create_region(world, player, active_locations, 'Gate 3', None)
world.regions += [gate_3_region, gate_3_boss_region]
if world.number_of_level_gates[player].value >= 4:
gate_4_boss_region = create_region(world, player, active_locations, 'Gate 4 Boss', [LocationName.gate_4_boss])
gate_4_region = create_region(world, player, active_locations, 'Gate 4', None)
world.regions += [gate_4_region, gate_4_boss_region]
if world.number_of_level_gates[player].value >= 5:
gate_5_boss_region = create_region(world, player, active_locations, 'Gate 5 Boss', [LocationName.gate_5_boss])
gate_5_region = create_region(world, player, active_locations, 'Gate 5', None)
world.regions += [gate_5_region, gate_5_boss_region]
city_escape_region_locations = [ city_escape_region_locations = [
LocationName.city_escape_1, LocationName.city_escape_1,
@ -106,10 +122,23 @@ def create_regions(world, player: int, active_locations):
LocationName.city_escape_3, LocationName.city_escape_3,
LocationName.city_escape_4, LocationName.city_escape_4,
LocationName.city_escape_5, LocationName.city_escape_5,
LocationName.city_escape_chao_1,
LocationName.city_escape_chao_2,
LocationName.city_escape_chao_3,
LocationName.city_escape_pipe_1,
LocationName.city_escape_pipe_2,
LocationName.city_escape_pipe_3,
LocationName.city_escape_pipe_4,
LocationName.city_escape_hidden_1,
LocationName.city_escape_hidden_2,
LocationName.city_escape_hidden_3,
LocationName.city_escape_hidden_4,
LocationName.city_escape_hidden_5,
LocationName.city_escape_beetle,
LocationName.city_escape_upgrade, LocationName.city_escape_upgrade,
] ]
city_escape_region = create_region(world, player, active_locations, LocationName.city_escape_region, city_escape_region = create_region(world, player, active_locations, LocationName.city_escape_region,
city_escape_region_locations, None) city_escape_region_locations)
metal_harbor_region_locations = [ metal_harbor_region_locations = [
LocationName.metal_harbor_1, LocationName.metal_harbor_1,
@ -117,10 +146,15 @@ def create_regions(world, player: int, active_locations):
LocationName.metal_harbor_3, LocationName.metal_harbor_3,
LocationName.metal_harbor_4, LocationName.metal_harbor_4,
LocationName.metal_harbor_5, LocationName.metal_harbor_5,
LocationName.metal_harbor_chao_1,
LocationName.metal_harbor_chao_2,
LocationName.metal_harbor_chao_3,
LocationName.metal_harbor_pipe_1,
LocationName.metal_harbor_beetle,
LocationName.metal_harbor_upgrade, LocationName.metal_harbor_upgrade,
] ]
metal_harbor_region = create_region(world, player, active_locations, LocationName.metal_harbor_region, metal_harbor_region = create_region(world, player, active_locations, LocationName.metal_harbor_region,
metal_harbor_region_locations, None) metal_harbor_region_locations)
green_forest_region_locations = [ green_forest_region_locations = [
LocationName.green_forest_1, LocationName.green_forest_1,
@ -128,10 +162,20 @@ def create_regions(world, player: int, active_locations):
LocationName.green_forest_3, LocationName.green_forest_3,
LocationName.green_forest_4, LocationName.green_forest_4,
LocationName.green_forest_5, LocationName.green_forest_5,
LocationName.green_forest_chao_1,
LocationName.green_forest_chao_2,
LocationName.green_forest_chao_3,
LocationName.green_forest_pipe_1,
LocationName.green_forest_pipe_2,
LocationName.green_forest_hidden_1,
LocationName.green_forest_hidden_2,
LocationName.green_forest_hidden_3,
LocationName.green_forest_hidden_4,
LocationName.green_forest_beetle,
LocationName.green_forest_upgrade, LocationName.green_forest_upgrade,
] ]
green_forest_region = create_region(world, player, active_locations, LocationName.green_forest_region, green_forest_region = create_region(world, player, active_locations, LocationName.green_forest_region,
green_forest_region_locations, None) green_forest_region_locations)
pyramid_cave_region_locations = [ pyramid_cave_region_locations = [
LocationName.pyramid_cave_1, LocationName.pyramid_cave_1,
@ -139,10 +183,18 @@ def create_regions(world, player: int, active_locations):
LocationName.pyramid_cave_3, LocationName.pyramid_cave_3,
LocationName.pyramid_cave_4, LocationName.pyramid_cave_4,
LocationName.pyramid_cave_5, LocationName.pyramid_cave_5,
LocationName.pyramid_cave_chao_1,
LocationName.pyramid_cave_chao_2,
LocationName.pyramid_cave_chao_3,
LocationName.pyramid_cave_pipe_1,
LocationName.pyramid_cave_pipe_2,
LocationName.pyramid_cave_pipe_3,
LocationName.pyramid_cave_pipe_4,
LocationName.pyramid_cave_beetle,
LocationName.pyramid_cave_upgrade, LocationName.pyramid_cave_upgrade,
] ]
pyramid_cave_region = create_region(world, player, active_locations, LocationName.pyramid_cave_region, pyramid_cave_region = create_region(world, player, active_locations, LocationName.pyramid_cave_region,
pyramid_cave_region_locations, None) pyramid_cave_region_locations)
crazy_gadget_region_locations = [ crazy_gadget_region_locations = [
LocationName.crazy_gadget_1, LocationName.crazy_gadget_1,
@ -150,10 +202,19 @@ def create_regions(world, player: int, active_locations):
LocationName.crazy_gadget_3, LocationName.crazy_gadget_3,
LocationName.crazy_gadget_4, LocationName.crazy_gadget_4,
LocationName.crazy_gadget_5, LocationName.crazy_gadget_5,
LocationName.crazy_gadget_chao_1,
LocationName.crazy_gadget_chao_2,
LocationName.crazy_gadget_chao_3,
LocationName.crazy_gadget_pipe_1,
LocationName.crazy_gadget_pipe_2,
LocationName.crazy_gadget_pipe_3,
LocationName.crazy_gadget_pipe_4,
LocationName.crazy_gadget_hidden_1,
LocationName.crazy_gadget_beetle,
LocationName.crazy_gadget_upgrade, LocationName.crazy_gadget_upgrade,
] ]
crazy_gadget_region = create_region(world, player, active_locations, LocationName.crazy_gadget_region, crazy_gadget_region = create_region(world, player, active_locations, LocationName.crazy_gadget_region,
crazy_gadget_region_locations, None) crazy_gadget_region_locations)
final_rush_region_locations = [ final_rush_region_locations = [
LocationName.final_rush_1, LocationName.final_rush_1,
@ -161,10 +222,16 @@ def create_regions(world, player: int, active_locations):
LocationName.final_rush_3, LocationName.final_rush_3,
LocationName.final_rush_4, LocationName.final_rush_4,
LocationName.final_rush_5, LocationName.final_rush_5,
LocationName.final_rush_chao_1,
LocationName.final_rush_chao_2,
LocationName.final_rush_chao_3,
LocationName.final_rush_pipe_1,
LocationName.final_rush_pipe_2,
LocationName.final_rush_beetle,
LocationName.final_rush_upgrade, LocationName.final_rush_upgrade,
] ]
final_rush_region = create_region(world, player, active_locations, LocationName.final_rush_region, final_rush_region = create_region(world, player, active_locations, LocationName.final_rush_region,
final_rush_region_locations, None) final_rush_region_locations)
prison_lane_region_locations = [ prison_lane_region_locations = [
LocationName.prison_lane_1, LocationName.prison_lane_1,
@ -172,10 +239,20 @@ def create_regions(world, player: int, active_locations):
LocationName.prison_lane_3, LocationName.prison_lane_3,
LocationName.prison_lane_4, LocationName.prison_lane_4,
LocationName.prison_lane_5, LocationName.prison_lane_5,
LocationName.prison_lane_chao_1,
LocationName.prison_lane_chao_2,
LocationName.prison_lane_chao_3,
LocationName.prison_lane_pipe_1,
LocationName.prison_lane_pipe_2,
LocationName.prison_lane_pipe_3,
LocationName.prison_lane_hidden_1,
LocationName.prison_lane_hidden_2,
LocationName.prison_lane_hidden_3,
LocationName.prison_lane_beetle,
LocationName.prison_lane_upgrade, LocationName.prison_lane_upgrade,
] ]
prison_lane_region = create_region(world, player, active_locations, LocationName.prison_lane_region, prison_lane_region = create_region(world, player, active_locations, LocationName.prison_lane_region,
prison_lane_region_locations, None) prison_lane_region_locations)
mission_street_region_locations = [ mission_street_region_locations = [
LocationName.mission_street_1, LocationName.mission_street_1,
@ -183,10 +260,20 @@ def create_regions(world, player: int, active_locations):
LocationName.mission_street_3, LocationName.mission_street_3,
LocationName.mission_street_4, LocationName.mission_street_4,
LocationName.mission_street_5, LocationName.mission_street_5,
LocationName.mission_street_chao_1,
LocationName.mission_street_chao_2,
LocationName.mission_street_chao_3,
LocationName.mission_street_pipe_1,
LocationName.mission_street_pipe_2,
LocationName.mission_street_pipe_3,
LocationName.mission_street_hidden_1,
LocationName.mission_street_hidden_2,
LocationName.mission_street_hidden_3,
LocationName.mission_street_beetle,
LocationName.mission_street_upgrade, LocationName.mission_street_upgrade,
] ]
mission_street_region = create_region(world, player, active_locations, LocationName.mission_street_region, mission_street_region = create_region(world, player, active_locations, LocationName.mission_street_region,
mission_street_region_locations, None) mission_street_region_locations)
route_101_region_locations = [ route_101_region_locations = [
LocationName.route_101_1, LocationName.route_101_1,
@ -196,7 +283,7 @@ def create_regions(world, player: int, active_locations):
LocationName.route_101_5, LocationName.route_101_5,
] ]
route_101_region = create_region(world, player, active_locations, LocationName.route_101_region, route_101_region = create_region(world, player, active_locations, LocationName.route_101_region,
route_101_region_locations, None) route_101_region_locations)
hidden_base_region_locations = [ hidden_base_region_locations = [
LocationName.hidden_base_1, LocationName.hidden_base_1,
@ -204,10 +291,18 @@ def create_regions(world, player: int, active_locations):
LocationName.hidden_base_3, LocationName.hidden_base_3,
LocationName.hidden_base_4, LocationName.hidden_base_4,
LocationName.hidden_base_5, LocationName.hidden_base_5,
LocationName.hidden_base_chao_1,
LocationName.hidden_base_chao_2,
LocationName.hidden_base_pipe_1,
LocationName.hidden_base_pipe_2,
LocationName.hidden_base_pipe_3,
LocationName.hidden_base_pipe_4,
LocationName.hidden_base_pipe_5,
LocationName.hidden_base_beetle,
LocationName.hidden_base_upgrade, LocationName.hidden_base_upgrade,
] ]
hidden_base_region = create_region(world, player, active_locations, LocationName.hidden_base_region, hidden_base_region = create_region(world, player, active_locations, LocationName.hidden_base_region,
hidden_base_region_locations, None) hidden_base_region_locations)
eternal_engine_region_locations = [ eternal_engine_region_locations = [
LocationName.eternal_engine_1, LocationName.eternal_engine_1,
@ -215,10 +310,19 @@ def create_regions(world, player: int, active_locations):
LocationName.eternal_engine_3, LocationName.eternal_engine_3,
LocationName.eternal_engine_4, LocationName.eternal_engine_4,
LocationName.eternal_engine_5, LocationName.eternal_engine_5,
LocationName.eternal_engine_chao_1,
LocationName.eternal_engine_chao_2,
LocationName.eternal_engine_chao_3,
LocationName.eternal_engine_pipe_1,
LocationName.eternal_engine_pipe_2,
LocationName.eternal_engine_pipe_3,
LocationName.eternal_engine_pipe_4,
LocationName.eternal_engine_pipe_5,
LocationName.eternal_engine_beetle,
LocationName.eternal_engine_upgrade, LocationName.eternal_engine_upgrade,
] ]
eternal_engine_region = create_region(world, player, active_locations, LocationName.eternal_engine_region, eternal_engine_region = create_region(world, player, active_locations, LocationName.eternal_engine_region,
eternal_engine_region_locations, None) eternal_engine_region_locations)
wild_canyon_region_locations = [ wild_canyon_region_locations = [
LocationName.wild_canyon_1, LocationName.wild_canyon_1,
@ -226,10 +330,17 @@ def create_regions(world, player: int, active_locations):
LocationName.wild_canyon_3, LocationName.wild_canyon_3,
LocationName.wild_canyon_4, LocationName.wild_canyon_4,
LocationName.wild_canyon_5, LocationName.wild_canyon_5,
LocationName.wild_canyon_chao_1,
LocationName.wild_canyon_chao_2,
LocationName.wild_canyon_chao_3,
LocationName.wild_canyon_pipe_1,
LocationName.wild_canyon_pipe_2,
LocationName.wild_canyon_pipe_3,
LocationName.wild_canyon_beetle,
LocationName.wild_canyon_upgrade, LocationName.wild_canyon_upgrade,
] ]
wild_canyon_region = create_region(world, player, active_locations, LocationName.wild_canyon_region, wild_canyon_region = create_region(world, player, active_locations, LocationName.wild_canyon_region,
wild_canyon_region_locations, None) wild_canyon_region_locations)
pumpkin_hill_region_locations = [ pumpkin_hill_region_locations = [
LocationName.pumpkin_hill_1, LocationName.pumpkin_hill_1,
@ -237,10 +348,15 @@ def create_regions(world, player: int, active_locations):
LocationName.pumpkin_hill_3, LocationName.pumpkin_hill_3,
LocationName.pumpkin_hill_4, LocationName.pumpkin_hill_4,
LocationName.pumpkin_hill_5, LocationName.pumpkin_hill_5,
LocationName.pumpkin_hill_chao_1,
LocationName.pumpkin_hill_chao_2,
LocationName.pumpkin_hill_chao_3,
LocationName.pumpkin_hill_pipe_1,
LocationName.pumpkin_hill_hidden_1,
LocationName.pumpkin_hill_upgrade, LocationName.pumpkin_hill_upgrade,
] ]
pumpkin_hill_region = create_region(world, player, active_locations, LocationName.pumpkin_hill_region, pumpkin_hill_region = create_region(world, player, active_locations, LocationName.pumpkin_hill_region,
pumpkin_hill_region_locations, None) pumpkin_hill_region_locations)
aquatic_mine_region_locations = [ aquatic_mine_region_locations = [
LocationName.aquatic_mine_1, LocationName.aquatic_mine_1,
@ -248,10 +364,17 @@ def create_regions(world, player: int, active_locations):
LocationName.aquatic_mine_3, LocationName.aquatic_mine_3,
LocationName.aquatic_mine_4, LocationName.aquatic_mine_4,
LocationName.aquatic_mine_5, LocationName.aquatic_mine_5,
LocationName.aquatic_mine_chao_1,
LocationName.aquatic_mine_chao_2,
LocationName.aquatic_mine_chao_3,
LocationName.aquatic_mine_pipe_1,
LocationName.aquatic_mine_pipe_2,
LocationName.aquatic_mine_pipe_3,
LocationName.aquatic_mine_beetle,
LocationName.aquatic_mine_upgrade, LocationName.aquatic_mine_upgrade,
] ]
aquatic_mine_region = create_region(world, player, active_locations, LocationName.aquatic_mine_region, aquatic_mine_region = create_region(world, player, active_locations, LocationName.aquatic_mine_region,
aquatic_mine_region_locations, None) aquatic_mine_region_locations)
death_chamber_region_locations = [ death_chamber_region_locations = [
LocationName.death_chamber_1, LocationName.death_chamber_1,
@ -259,10 +382,19 @@ def create_regions(world, player: int, active_locations):
LocationName.death_chamber_3, LocationName.death_chamber_3,
LocationName.death_chamber_4, LocationName.death_chamber_4,
LocationName.death_chamber_5, LocationName.death_chamber_5,
LocationName.death_chamber_chao_1,
LocationName.death_chamber_chao_2,
LocationName.death_chamber_chao_3,
LocationName.death_chamber_pipe_1,
LocationName.death_chamber_pipe_2,
LocationName.death_chamber_pipe_3,
LocationName.death_chamber_hidden_1,
LocationName.death_chamber_hidden_2,
LocationName.death_chamber_beetle,
LocationName.death_chamber_upgrade, LocationName.death_chamber_upgrade,
] ]
death_chamber_region = create_region(world, player, active_locations, LocationName.death_chamber_region, death_chamber_region = create_region(world, player, active_locations, LocationName.death_chamber_region,
death_chamber_region_locations, None) death_chamber_region_locations)
meteor_herd_region_locations = [ meteor_herd_region_locations = [
LocationName.meteor_herd_1, LocationName.meteor_herd_1,
@ -270,10 +402,17 @@ def create_regions(world, player: int, active_locations):
LocationName.meteor_herd_3, LocationName.meteor_herd_3,
LocationName.meteor_herd_4, LocationName.meteor_herd_4,
LocationName.meteor_herd_5, LocationName.meteor_herd_5,
LocationName.meteor_herd_chao_1,
LocationName.meteor_herd_chao_2,
LocationName.meteor_herd_chao_3,
LocationName.meteor_herd_pipe_1,
LocationName.meteor_herd_pipe_2,
LocationName.meteor_herd_pipe_3,
LocationName.meteor_herd_beetle,
LocationName.meteor_herd_upgrade, LocationName.meteor_herd_upgrade,
] ]
meteor_herd_region = create_region(world, player, active_locations, LocationName.meteor_herd_region, meteor_herd_region = create_region(world, player, active_locations, LocationName.meteor_herd_region,
meteor_herd_region_locations, None) meteor_herd_region_locations)
radical_highway_region_locations = [ radical_highway_region_locations = [
LocationName.radical_highway_1, LocationName.radical_highway_1,
@ -281,10 +420,20 @@ def create_regions(world, player: int, active_locations):
LocationName.radical_highway_3, LocationName.radical_highway_3,
LocationName.radical_highway_4, LocationName.radical_highway_4,
LocationName.radical_highway_5, LocationName.radical_highway_5,
LocationName.radical_highway_chao_1,
LocationName.radical_highway_chao_2,
LocationName.radical_highway_chao_3,
LocationName.radical_highway_pipe_1,
LocationName.radical_highway_pipe_2,
LocationName.radical_highway_pipe_3,
LocationName.radical_highway_hidden_1,
LocationName.radical_highway_hidden_2,
LocationName.radical_highway_hidden_3,
LocationName.radical_highway_beetle,
LocationName.radical_highway_upgrade, LocationName.radical_highway_upgrade,
] ]
radical_highway_region = create_region(world, player, active_locations, LocationName.radical_highway_region, radical_highway_region = create_region(world, player, active_locations, LocationName.radical_highway_region,
radical_highway_region_locations, None) radical_highway_region_locations)
white_jungle_region_locations = [ white_jungle_region_locations = [
LocationName.white_jungle_1, LocationName.white_jungle_1,
@ -292,10 +441,21 @@ def create_regions(world, player: int, active_locations):
LocationName.white_jungle_3, LocationName.white_jungle_3,
LocationName.white_jungle_4, LocationName.white_jungle_4,
LocationName.white_jungle_5, LocationName.white_jungle_5,
LocationName.white_jungle_chao_1,
LocationName.white_jungle_chao_2,
LocationName.white_jungle_chao_3,
LocationName.white_jungle_pipe_1,
LocationName.white_jungle_pipe_2,
LocationName.white_jungle_pipe_3,
LocationName.white_jungle_pipe_4,
LocationName.white_jungle_hidden_1,
LocationName.white_jungle_hidden_2,
LocationName.white_jungle_hidden_3,
LocationName.white_jungle_beetle,
LocationName.white_jungle_upgrade, LocationName.white_jungle_upgrade,
] ]
white_jungle_region = create_region(world, player, active_locations, LocationName.white_jungle_region, white_jungle_region = create_region(world, player, active_locations, LocationName.white_jungle_region,
white_jungle_region_locations, None) white_jungle_region_locations)
sky_rail_region_locations = [ sky_rail_region_locations = [
LocationName.sky_rail_1, LocationName.sky_rail_1,
@ -303,10 +463,20 @@ def create_regions(world, player: int, active_locations):
LocationName.sky_rail_3, LocationName.sky_rail_3,
LocationName.sky_rail_4, LocationName.sky_rail_4,
LocationName.sky_rail_5, LocationName.sky_rail_5,
LocationName.sky_rail_chao_1,
LocationName.sky_rail_chao_2,
LocationName.sky_rail_chao_3,
LocationName.sky_rail_pipe_1,
LocationName.sky_rail_pipe_2,
LocationName.sky_rail_pipe_3,
LocationName.sky_rail_pipe_4,
LocationName.sky_rail_pipe_5,
LocationName.sky_rail_pipe_6,
LocationName.sky_rail_beetle,
LocationName.sky_rail_upgrade, LocationName.sky_rail_upgrade,
] ]
sky_rail_region = create_region(world, player, active_locations, LocationName.sky_rail_region, sky_rail_region = create_region(world, player, active_locations, LocationName.sky_rail_region,
sky_rail_region_locations, None) sky_rail_region_locations)
final_chase_region_locations = [ final_chase_region_locations = [
LocationName.final_chase_1, LocationName.final_chase_1,
@ -314,10 +484,17 @@ def create_regions(world, player: int, active_locations):
LocationName.final_chase_3, LocationName.final_chase_3,
LocationName.final_chase_4, LocationName.final_chase_4,
LocationName.final_chase_5, LocationName.final_chase_5,
LocationName.final_chase_chao_1,
LocationName.final_chase_chao_2,
LocationName.final_chase_chao_3,
LocationName.final_chase_pipe_1,
LocationName.final_chase_pipe_2,
LocationName.final_chase_pipe_3,
LocationName.final_chase_beetle,
LocationName.final_chase_upgrade, LocationName.final_chase_upgrade,
] ]
final_chase_region = create_region(world, player, active_locations, LocationName.final_chase_region, final_chase_region = create_region(world, player, active_locations, LocationName.final_chase_region,
final_chase_region_locations, None) final_chase_region_locations)
iron_gate_region_locations = [ iron_gate_region_locations = [
LocationName.iron_gate_1, LocationName.iron_gate_1,
@ -325,10 +502,19 @@ def create_regions(world, player: int, active_locations):
LocationName.iron_gate_3, LocationName.iron_gate_3,
LocationName.iron_gate_4, LocationName.iron_gate_4,
LocationName.iron_gate_5, LocationName.iron_gate_5,
LocationName.iron_gate_chao_1,
LocationName.iron_gate_chao_2,
LocationName.iron_gate_chao_3,
LocationName.iron_gate_pipe_1,
LocationName.iron_gate_pipe_2,
LocationName.iron_gate_pipe_3,
LocationName.iron_gate_pipe_4,
LocationName.iron_gate_pipe_5,
LocationName.iron_gate_beetle,
LocationName.iron_gate_upgrade, LocationName.iron_gate_upgrade,
] ]
iron_gate_region = create_region(world, player, active_locations, LocationName.iron_gate_region, iron_gate_region = create_region(world, player, active_locations, LocationName.iron_gate_region,
iron_gate_region_locations, None) iron_gate_region_locations)
sand_ocean_region_locations = [ sand_ocean_region_locations = [
LocationName.sand_ocean_1, LocationName.sand_ocean_1,
@ -336,10 +522,19 @@ def create_regions(world, player: int, active_locations):
LocationName.sand_ocean_3, LocationName.sand_ocean_3,
LocationName.sand_ocean_4, LocationName.sand_ocean_4,
LocationName.sand_ocean_5, LocationName.sand_ocean_5,
LocationName.sand_ocean_chao_1,
LocationName.sand_ocean_chao_2,
LocationName.sand_ocean_chao_3,
LocationName.sand_ocean_pipe_1,
LocationName.sand_ocean_pipe_2,
LocationName.sand_ocean_pipe_3,
LocationName.sand_ocean_pipe_4,
LocationName.sand_ocean_pipe_5,
LocationName.sand_ocean_beetle,
LocationName.sand_ocean_upgrade, LocationName.sand_ocean_upgrade,
] ]
sand_ocean_region = create_region(world, player, active_locations, LocationName.sand_ocean_region, sand_ocean_region = create_region(world, player, active_locations, LocationName.sand_ocean_region,
sand_ocean_region_locations, None) sand_ocean_region_locations)
lost_colony_region_locations = [ lost_colony_region_locations = [
LocationName.lost_colony_1, LocationName.lost_colony_1,
@ -347,10 +542,17 @@ def create_regions(world, player: int, active_locations):
LocationName.lost_colony_3, LocationName.lost_colony_3,
LocationName.lost_colony_4, LocationName.lost_colony_4,
LocationName.lost_colony_5, LocationName.lost_colony_5,
LocationName.lost_colony_chao_1,
LocationName.lost_colony_chao_2,
LocationName.lost_colony_chao_3,
LocationName.lost_colony_pipe_1,
LocationName.lost_colony_pipe_2,
LocationName.lost_colony_hidden_1,
LocationName.lost_colony_beetle,
LocationName.lost_colony_upgrade, LocationName.lost_colony_upgrade,
] ]
lost_colony_region = create_region(world, player, active_locations, LocationName.lost_colony_region, lost_colony_region = create_region(world, player, active_locations, LocationName.lost_colony_region,
lost_colony_region_locations, None) lost_colony_region_locations)
weapons_bed_region_locations = [ weapons_bed_region_locations = [
LocationName.weapons_bed_1, LocationName.weapons_bed_1,
@ -358,10 +560,18 @@ def create_regions(world, player: int, active_locations):
LocationName.weapons_bed_3, LocationName.weapons_bed_3,
LocationName.weapons_bed_4, LocationName.weapons_bed_4,
LocationName.weapons_bed_5, LocationName.weapons_bed_5,
LocationName.weapons_bed_chao_1,
LocationName.weapons_bed_chao_2,
LocationName.weapons_bed_chao_3,
LocationName.weapons_bed_pipe_1,
LocationName.weapons_bed_pipe_2,
LocationName.weapons_bed_pipe_3,
LocationName.weapons_bed_pipe_4,
LocationName.weapons_bed_pipe_5,
LocationName.weapons_bed_upgrade, LocationName.weapons_bed_upgrade,
] ]
weapons_bed_region = create_region(world, player, active_locations, LocationName.weapons_bed_region, weapons_bed_region = create_region(world, player, active_locations, LocationName.weapons_bed_region,
weapons_bed_region_locations, None) weapons_bed_region_locations)
cosmic_wall_region_locations = [ cosmic_wall_region_locations = [
LocationName.cosmic_wall_1, LocationName.cosmic_wall_1,
@ -369,10 +579,19 @@ def create_regions(world, player: int, active_locations):
LocationName.cosmic_wall_3, LocationName.cosmic_wall_3,
LocationName.cosmic_wall_4, LocationName.cosmic_wall_4,
LocationName.cosmic_wall_5, LocationName.cosmic_wall_5,
LocationName.cosmic_wall_chao_1,
LocationName.cosmic_wall_chao_2,
LocationName.cosmic_wall_chao_3,
LocationName.cosmic_wall_pipe_1,
LocationName.cosmic_wall_pipe_2,
LocationName.cosmic_wall_pipe_3,
LocationName.cosmic_wall_pipe_4,
LocationName.cosmic_wall_pipe_5,
LocationName.cosmic_wall_beetle,
LocationName.cosmic_wall_upgrade, LocationName.cosmic_wall_upgrade,
] ]
cosmic_wall_region = create_region(world, player, active_locations, LocationName.cosmic_wall_region, cosmic_wall_region = create_region(world, player, active_locations, LocationName.cosmic_wall_region,
cosmic_wall_region_locations, None) cosmic_wall_region_locations)
dry_lagoon_region_locations = [ dry_lagoon_region_locations = [
LocationName.dry_lagoon_1, LocationName.dry_lagoon_1,
@ -380,10 +599,16 @@ def create_regions(world, player: int, active_locations):
LocationName.dry_lagoon_3, LocationName.dry_lagoon_3,
LocationName.dry_lagoon_4, LocationName.dry_lagoon_4,
LocationName.dry_lagoon_5, LocationName.dry_lagoon_5,
LocationName.dry_lagoon_chao_1,
LocationName.dry_lagoon_chao_2,
LocationName.dry_lagoon_chao_3,
LocationName.dry_lagoon_pipe_1,
LocationName.dry_lagoon_hidden_1,
LocationName.dry_lagoon_beetle,
LocationName.dry_lagoon_upgrade, LocationName.dry_lagoon_upgrade,
] ]
dry_lagoon_region = create_region(world, player, active_locations, LocationName.dry_lagoon_region, dry_lagoon_region = create_region(world, player, active_locations, LocationName.dry_lagoon_region,
dry_lagoon_region_locations, None) dry_lagoon_region_locations)
egg_quarters_region_locations = [ egg_quarters_region_locations = [
LocationName.egg_quarters_1, LocationName.egg_quarters_1,
@ -391,10 +616,18 @@ def create_regions(world, player: int, active_locations):
LocationName.egg_quarters_3, LocationName.egg_quarters_3,
LocationName.egg_quarters_4, LocationName.egg_quarters_4,
LocationName.egg_quarters_5, LocationName.egg_quarters_5,
LocationName.egg_quarters_chao_1,
LocationName.egg_quarters_chao_2,
LocationName.egg_quarters_chao_3,
LocationName.egg_quarters_pipe_1,
LocationName.egg_quarters_pipe_2,
LocationName.egg_quarters_hidden_1,
LocationName.egg_quarters_hidden_2,
LocationName.egg_quarters_beetle,
LocationName.egg_quarters_upgrade, LocationName.egg_quarters_upgrade,
] ]
egg_quarters_region = create_region(world, player, active_locations, LocationName.egg_quarters_region, egg_quarters_region = create_region(world, player, active_locations, LocationName.egg_quarters_region,
egg_quarters_region_locations, None) egg_quarters_region_locations)
security_hall_region_locations = [ security_hall_region_locations = [
LocationName.security_hall_1, LocationName.security_hall_1,
@ -402,10 +635,16 @@ def create_regions(world, player: int, active_locations):
LocationName.security_hall_3, LocationName.security_hall_3,
LocationName.security_hall_4, LocationName.security_hall_4,
LocationName.security_hall_5, LocationName.security_hall_5,
LocationName.security_hall_chao_1,
LocationName.security_hall_chao_2,
LocationName.security_hall_chao_3,
LocationName.security_hall_pipe_1,
LocationName.security_hall_hidden_1,
LocationName.security_hall_beetle,
LocationName.security_hall_upgrade, LocationName.security_hall_upgrade,
] ]
security_hall_region = create_region(world, player, active_locations, LocationName.security_hall_region, security_hall_region = create_region(world, player, active_locations, LocationName.security_hall_region,
security_hall_region_locations, None) security_hall_region_locations)
route_280_region_locations = [ route_280_region_locations = [
LocationName.route_280_1, LocationName.route_280_1,
@ -415,7 +654,7 @@ def create_regions(world, player: int, active_locations):
LocationName.route_280_5, LocationName.route_280_5,
] ]
route_280_region = create_region(world, player, active_locations, LocationName.route_280_region, route_280_region = create_region(world, player, active_locations, LocationName.route_280_region,
route_280_region_locations, None) route_280_region_locations)
mad_space_region_locations = [ mad_space_region_locations = [
LocationName.mad_space_1, LocationName.mad_space_1,
@ -423,10 +662,18 @@ def create_regions(world, player: int, active_locations):
LocationName.mad_space_3, LocationName.mad_space_3,
LocationName.mad_space_4, LocationName.mad_space_4,
LocationName.mad_space_5, LocationName.mad_space_5,
LocationName.mad_space_chao_1,
LocationName.mad_space_chao_2,
LocationName.mad_space_chao_3,
LocationName.mad_space_pipe_1,
LocationName.mad_space_pipe_2,
LocationName.mad_space_pipe_3,
LocationName.mad_space_pipe_4,
LocationName.mad_space_beetle,
LocationName.mad_space_upgrade, LocationName.mad_space_upgrade,
] ]
mad_space_region = create_region(world, player, active_locations, LocationName.mad_space_region, mad_space_region = create_region(world, player, active_locations, LocationName.mad_space_region,
mad_space_region_locations, None) mad_space_region_locations)
cannon_core_region_locations = [ cannon_core_region_locations = [
LocationName.cannon_core_1, LocationName.cannon_core_1,
@ -434,9 +681,19 @@ def create_regions(world, player: int, active_locations):
LocationName.cannon_core_3, LocationName.cannon_core_3,
LocationName.cannon_core_4, LocationName.cannon_core_4,
LocationName.cannon_core_5, LocationName.cannon_core_5,
LocationName.cannon_core_chao_1,
LocationName.cannon_core_chao_2,
LocationName.cannon_core_chao_3,
LocationName.cannon_core_pipe_1,
LocationName.cannon_core_pipe_2,
LocationName.cannon_core_pipe_3,
LocationName.cannon_core_pipe_4,
LocationName.cannon_core_pipe_5,
LocationName.cannon_core_hidden_1,
LocationName.cannon_core_beetle,
] ]
cannon_core_region = create_region(world, player, active_locations, LocationName.cannon_core_region, cannon_core_region = create_region(world, player, active_locations, LocationName.cannon_core_region,
cannon_core_region_locations, None) cannon_core_region_locations)
chao_garden_beginner_region_locations = [ chao_garden_beginner_region_locations = [
LocationName.chao_race_crab_pool_1, LocationName.chao_race_crab_pool_1,
@ -455,9 +712,38 @@ def create_regions(world, player: int, active_locations):
LocationName.chao_beginner_karate, LocationName.chao_beginner_karate,
] ]
chao_garden_beginner_region = create_region(world, player, active_locations, LocationName.chao_garden_beginner_region, chao_garden_beginner_region = create_region(world, player, active_locations, LocationName.chao_garden_beginner_region,
chao_garden_beginner_region_locations, None) chao_garden_beginner_region_locations)
chao_garden_intermediate_region_locations = [ chao_garden_intermediate_region_locations = [
LocationName.chao_race_challenge_1,
LocationName.chao_race_challenge_2,
LocationName.chao_race_challenge_3,
LocationName.chao_race_challenge_4,
LocationName.chao_race_challenge_5,
LocationName.chao_race_challenge_6,
LocationName.chao_race_challenge_7,
LocationName.chao_race_challenge_8,
LocationName.chao_race_challenge_9,
LocationName.chao_race_challenge_10,
LocationName.chao_race_challenge_11,
LocationName.chao_race_challenge_12,
LocationName.chao_race_hero_1,
LocationName.chao_race_hero_2,
LocationName.chao_race_hero_3,
LocationName.chao_race_hero_4,
LocationName.chao_race_dark_1,
LocationName.chao_race_dark_2,
LocationName.chao_race_dark_3,
LocationName.chao_race_dark_4,
LocationName.chao_standard_karate,
]
chao_garden_intermediate_region = create_region(world, player, active_locations, LocationName.chao_garden_intermediate_region,
chao_garden_intermediate_region_locations)
chao_garden_expert_region_locations = [
LocationName.chao_race_aquamarine_1, LocationName.chao_race_aquamarine_1,
LocationName.chao_race_aquamarine_2, LocationName.chao_race_aquamarine_2,
LocationName.chao_race_aquamarine_3, LocationName.chao_race_aquamarine_3,
@ -489,61 +775,34 @@ def create_regions(world, player: int, active_locations):
LocationName.chao_race_diamond_4, LocationName.chao_race_diamond_4,
LocationName.chao_race_diamond_5, LocationName.chao_race_diamond_5,
LocationName.chao_standard_karate,
]
chao_garden_intermediate_region = create_region(world, player, active_locations, LocationName.chao_garden_intermediate_region,
chao_garden_intermediate_region_locations, None)
chao_garden_expert_region_locations = [
LocationName.chao_race_challenge_1,
LocationName.chao_race_challenge_2,
LocationName.chao_race_challenge_3,
LocationName.chao_race_challenge_4,
LocationName.chao_race_challenge_5,
LocationName.chao_race_challenge_6,
LocationName.chao_race_challenge_7,
LocationName.chao_race_challenge_8,
LocationName.chao_race_challenge_9,
LocationName.chao_race_challenge_10,
LocationName.chao_race_challenge_11,
LocationName.chao_race_challenge_12,
LocationName.chao_race_hero_1,
LocationName.chao_race_hero_2,
LocationName.chao_race_hero_3,
LocationName.chao_race_hero_4,
LocationName.chao_race_dark_1,
LocationName.chao_race_dark_2,
LocationName.chao_race_dark_3,
LocationName.chao_race_dark_4,
LocationName.chao_expert_karate, LocationName.chao_expert_karate,
LocationName.chao_super_karate, LocationName.chao_super_karate,
] ]
chao_garden_expert_region = create_region(world, player, active_locations, LocationName.chao_garden_expert_region, chao_garden_expert_region = create_region(world, player, active_locations, LocationName.chao_garden_expert_region,
chao_garden_expert_region_locations, None) chao_garden_expert_region_locations)
if world.goal[player] == 0 or world.goal[player] == 2:
biolizard_region_locations = [
LocationName.finalhazard,
]
biolizard_region = create_region(world, player, active_locations, LocationName.biolizard_region,
biolizard_region_locations)
world.regions += [biolizard_region]
if world.goal[player] == 1 or world.goal[player] == 2:
green_hill_region_locations = [
LocationName.green_hill,
LocationName.green_hill_chao_1,
]
green_hill_region = create_region(world, player, active_locations, LocationName.green_hill_region,
green_hill_region_locations)
world.regions += [green_hill_region]
biolizard_region_locations = [
LocationName.biolizard,
]
biolizard_region = create_region(world, player, active_locations, LocationName.biolizard_region,
biolizard_region_locations, None)
# Set up the regions correctly. # Set up the regions correctly.
world.regions += [ world.regions += [
menu_region, menu_region,
gate_0_region, gate_0_region,
gate_1_region,
gate_2_region,
gate_3_region,
gate_4_region,
gate_5_region,
gate_1_boss_region,
gate_2_boss_region,
gate_3_boss_region,
gate_4_boss_region,
gate_5_boss_region,
city_escape_region, city_escape_region,
metal_harbor_region, metal_harbor_region,
green_forest_region, green_forest_region,
@ -578,19 +837,35 @@ def create_regions(world, player: int, active_locations):
chao_garden_beginner_region, chao_garden_beginner_region,
chao_garden_intermediate_region, chao_garden_intermediate_region,
chao_garden_expert_region, chao_garden_expert_region,
biolizard_region,
] ]
def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_emblems, gate_bosses): def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_emblems, gate_bosses, first_cannons_core_mission: str, final_cannons_core_mission: str):
names: typing.Dict[str, int] = {} names: typing.Dict[str, int] = {}
connect(world, player, names, 'Menu', LocationName.gate_0_region) connect(world, player, names, 'Menu', LocationName.gate_0_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.cannon_core_region, connect(world, player, names, LocationName.gate_0_region, LocationName.cannon_core_region,
lambda state: (state.has(ItemName.emblem, player, cannon_core_emblems))) lambda state: (state.has(ItemName.emblem, player, cannon_core_emblems)))
connect(world, player, names, LocationName.cannon_core_region, LocationName.biolizard_region, if world.goal[player] == 0:
lambda state: (state.can_reach(LocationName.cannon_core_1, "Location", player))) required_mission_name = first_cannons_core_mission
if world.required_cannons_core_missions[player].value == 1:
required_mission_name = final_cannons_core_mission
connect(world, player, names, LocationName.cannon_core_region, LocationName.biolizard_region,
lambda state: (state.can_reach(required_mission_name, "Location", player)))
elif world.goal[player] == 1 or world.goal[player] == 2:
connect(world, player, names, 'Menu', LocationName.green_hill_region,
lambda state: (state.has(ItemName.white_emerald, player) and
state.has(ItemName.red_emerald, player) and
state.has(ItemName.cyan_emerald, player) and
state.has(ItemName.purple_emerald, player) and
state.has(ItemName.green_emerald, player) and
state.has(ItemName.yellow_emerald, player) and
state.has(ItemName.blue_emerald, player)))
if world.goal[player] == 2:
connect(world, player, names, LocationName.green_hill_region, LocationName.biolizard_region)
for i in range(len(gates[0].gate_levels)): for i in range(len(gates[0].gate_levels)):
connect(world, player, names, LocationName.gate_0_region, shuffleable_regions[gates[0].gate_levels[i]]) connect(world, player, names, LocationName.gate_0_region, shuffleable_regions[gates[0].gate_levels[i]])
@ -687,8 +962,7 @@ def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_em
connect(world, player, names, LocationName.gate_4_region, LocationName.chao_garden_expert_region) connect(world, player, names, LocationName.gate_4_region, LocationName.chao_garden_expert_region)
def create_region(world: MultiWorld, player: int, active_locations, name: str, locations=None, exits=None): def create_region(world: MultiWorld, player: int, active_locations, name: str, locations=None):
# Shamelessly stolen from the ROR2 definition
ret = Region(name, None, name, player) ret = Region(name, None, name, player)
ret.multiworld = world ret.multiworld = world
if locations: if locations:
@ -697,9 +971,6 @@ def create_region(world: MultiWorld, player: int, active_locations, name: str, l
if loc_id: if loc_id:
location = SA2BLocation(player, location, loc_id, ret) location = SA2BLocation(player, location, loc_id, ret)
ret.locations.append(location) ret.locations.append(location)
if exits:
for exit in exits:
ret.exits.append(Entrance(player, exit, ret))
return ret return ret

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@ import typing
import math import math
from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification
from .Items import SA2BItem, ItemData, item_table, upgrades_table, junk_table, trap_table from .Items import SA2BItem, ItemData, item_table, upgrades_table, emeralds_table, junk_table, trap_table, item_groups
from .Locations import SA2BLocation, all_locations, setup_locations from .Locations import SA2BLocation, all_locations, setup_locations
from .Options import sa2b_options from .Options import sa2b_options
from .Regions import create_regions, shuffleable_regions, connect_regions, LevelGate, gate_0_whitelist_regions, \ from .Regions import create_regions, shuffleable_regions, connect_regions, LevelGate, gate_0_whitelist_regions, \
@ -11,6 +11,7 @@ from .Rules import set_rules
from .Names import ItemName, LocationName from .Names import ItemName, LocationName
from ..AutoWorld import WebWorld, World from ..AutoWorld import WebWorld, World
from .GateBosses import get_gate_bosses, get_boss_name from .GateBosses import get_gate_bosses, get_boss_name
from .Missions import get_mission_table, get_mission_count_table, get_first_and_last_cannons_core_missions
import Patch import Patch
@ -29,7 +30,7 @@ class SA2BWeb(WebWorld):
tutorials = [setup_en] tutorials = [setup_en]
def check_for_impossible_shuffle(shuffled_levels: typing.List[int], gate_0_range: int, world: MultiWorld): def check_for_impossible_shuffle(shuffled_levels: typing.List[int], gate_0_range: int, multiworld: MultiWorld):
blacklist_level_count = 0 blacklist_level_count = 0
for i in range(gate_0_range): for i in range(gate_0_range):
@ -37,7 +38,7 @@ def check_for_impossible_shuffle(shuffled_levels: typing.List[int], gate_0_range
blacklist_level_count += 1 blacklist_level_count += 1
if blacklist_level_count == gate_0_range: if blacklist_level_count == gate_0_range:
index_to_swap = world.random.randint(0, gate_0_range) index_to_swap = multiworld.random.randint(0, gate_0_range)
for i in range(len(shuffled_levels)): for i in range(len(shuffled_levels)):
if shuffled_levels[i] in gate_0_whitelist_regions: if shuffled_levels[i] in gate_0_whitelist_regions:
shuffled_levels[i], shuffled_levels[index_to_swap] = shuffled_levels[index_to_swap], shuffled_levels[i] shuffled_levels[i], shuffled_levels[index_to_swap] = shuffled_levels[index_to_swap], shuffled_levels[i]
@ -51,14 +52,17 @@ class SA2BWorld(World):
game: str = "Sonic Adventure 2 Battle" game: str = "Sonic Adventure 2 Battle"
option_definitions = sa2b_options option_definitions = sa2b_options
topology_present = False topology_present = False
data_version = 2 data_version = 3
item_name_groups = item_groups
item_name_to_id = {name: data.code for name, data in item_table.items()} item_name_to_id = {name: data.code for name, data in item_table.items()}
location_name_to_id = all_locations location_name_to_id = all_locations
location_table: typing.Dict[str, int] location_table: typing.Dict[str, int]
music_map: typing.Dict[int, int] music_map: typing.Dict[int, int]
mission_map: typing.Dict[int, int]
mission_count_map: typing.Dict[int, int]
emblems_for_cannons_core: int emblems_for_cannons_core: int
region_emblem_map: typing.Dict[int, int] region_emblem_map: typing.Dict[int, int]
gate_costs: typing.Dict[int, int] gate_costs: typing.Dict[int, int]
@ -67,15 +71,22 @@ class SA2BWorld(World):
def _get_slot_data(self): def _get_slot_data(self):
return { return {
"ModVersion": 101, "ModVersion": 200,
"Goal": self.multiworld.goal[self.player].value,
"MusicMap": self.music_map, "MusicMap": self.music_map,
"MissionMap": self.mission_map,
"MissionCountMap": self.mission_count_map,
"MusicShuffle": self.multiworld.music_shuffle[self.player].value, "MusicShuffle": self.multiworld.music_shuffle[self.player].value,
"Narrator": self.multiworld.narrator[self.player].value,
"RequiredRank": self.multiworld.required_rank[self.player].value, "RequiredRank": self.multiworld.required_rank[self.player].value,
"ChaoKeys": self.multiworld.keysanity[self.player].value,
"Whistlesanity": self.multiworld.whistlesanity[self.player].value,
"GoldBeetles": self.multiworld.beetlesanity[self.player].value,
"ChaoRaceChecks": self.multiworld.chao_race_checks[self.player].value, "ChaoRaceChecks": self.multiworld.chao_race_checks[self.player].value,
"ChaoGardenDifficulty": self.multiworld.chao_garden_difficulty[self.player].value, "ChaoGardenDifficulty": self.multiworld.chao_garden_difficulty[self.player].value,
"DeathLink": self.multiworld.death_link[self.player].value, "DeathLink": self.multiworld.death_link[self.player].value,
"IncludeMissions": self.multiworld.include_missions[self.player].value,
"EmblemPercentageForCannonsCore": self.multiworld.emblem_percentage_for_cannons_core[self.player].value, "EmblemPercentageForCannonsCore": self.multiworld.emblem_percentage_for_cannons_core[self.player].value,
"RequiredCannonsCoreMissions": self.multiworld.required_cannons_core_missions[self.player].value,
"NumberOfLevelGates": self.multiworld.number_of_level_gates[self.player].value, "NumberOfLevelGates": self.multiworld.number_of_level_gates[self.player].value,
"LevelGateDistribution": self.multiworld.level_gate_distribution[self.player].value, "LevelGateDistribution": self.multiworld.level_gate_distribution[self.player].value,
"EmblemsForCannonsCore": self.emblems_for_cannons_core, "EmblemsForCannonsCore": self.emblems_for_cannons_core,
@ -137,7 +148,10 @@ class SA2BWorld(World):
self.gate_bosses = get_gate_bosses(self.multiworld, self.player) self.gate_bosses = get_gate_bosses(self.multiworld, self.player)
def generate_basic(self): def generate_basic(self):
self.multiworld.get_location(LocationName.biolizard, self.player).place_locked_item(self.create_item(ItemName.maria)) if self.multiworld.goal[self.player].value == 0 or self.multiworld.goal[self.player].value == 2:
self.multiworld.get_location(LocationName.finalhazard, self.player).place_locked_item(self.create_item(ItemName.maria))
elif self.multiworld.goal[self.player].value == 1:
self.multiworld.get_location(LocationName.green_hill, self.player).place_locked_item(self.create_item(ItemName.maria))
itempool: typing.List[SA2BItem] = [] itempool: typing.List[SA2BItem] = []
@ -149,6 +163,11 @@ class SA2BWorld(World):
for item in {**upgrades_table}: for item in {**upgrades_table}:
itempool += self._create_items(item) itempool += self._create_items(item)
if self.multiworld.goal[self.player].value == 1 or self.multiworld.goal[self.player].value == 2:
# Some flavor of Chaos Emerald Hunt
for item in {**emeralds_table}:
itempool += self._create_items(item)
# Cap at 180 Emblems # Cap at 180 Emblems
raw_emblem_count = total_required_locations - len(itempool) raw_emblem_count = total_required_locations - len(itempool)
total_emblem_count = min(raw_emblem_count, 180) total_emblem_count = min(raw_emblem_count, 180)
@ -195,7 +214,9 @@ class SA2BWorld(World):
self.region_emblem_map = dict(zip(shuffled_region_list, emblem_requirement_list)) self.region_emblem_map = dict(zip(shuffled_region_list, emblem_requirement_list))
connect_regions(self.multiworld, self.player, gates, self.emblems_for_cannons_core, self.gate_bosses) first_cannons_core_mission, final_cannons_core_mission = get_first_and_last_cannons_core_missions(self.mission_map, self.mission_count_map)
connect_regions(self.multiworld, self.player, gates, self.emblems_for_cannons_core, self.gate_bosses, first_cannons_core_mission, final_cannons_core_mission)
max_required_emblems = max(max(emblem_requirement_list), self.emblems_for_cannons_core) max_required_emblems = max(max(emblem_requirement_list), self.emblems_for_cannons_core)
itempool += [self.create_item(ItemName.emblem) for _ in range(max_required_emblems)] itempool += [self.create_item(ItemName.emblem) for _ in range(max_required_emblems)]
@ -210,6 +231,9 @@ class SA2BWorld(World):
trap_weights += ([ItemName.timestop_trap] * self.multiworld.timestop_trap_weight[self.player].value) trap_weights += ([ItemName.timestop_trap] * self.multiworld.timestop_trap_weight[self.player].value)
trap_weights += ([ItemName.confuse_trap] * self.multiworld.confusion_trap_weight[self.player].value) trap_weights += ([ItemName.confuse_trap] * self.multiworld.confusion_trap_weight[self.player].value)
trap_weights += ([ItemName.tiny_trap] * self.multiworld.tiny_trap_weight[self.player].value) trap_weights += ([ItemName.tiny_trap] * self.multiworld.tiny_trap_weight[self.player].value)
trap_weights += ([ItemName.gravity_trap] * self.multiworld.gravity_trap_weight[self.player].value)
trap_weights += ([ItemName.exposition_trap] * self.multiworld.exposition_trap_weight[self.player].value)
#trap_weights += ([ItemName.darkness_trap] * self.multiworld.darkness_trap_weight[self.player].value)
junk_count += extra_junk_count junk_count += extra_junk_count
trap_count = 0 if (len(trap_weights) == 0) else math.ceil(junk_count * (self.multiworld.trap_fill_percentage[self.player].value / 100.0)) trap_count = 0 if (len(trap_weights) == 0) else math.ceil(junk_count * (self.multiworld.trap_fill_percentage[self.player].value / 100.0))
@ -237,17 +261,59 @@ class SA2BWorld(World):
musiclist_o = list(range(0, 47)) musiclist_o = list(range(0, 47))
musiclist_s = musiclist_o.copy() musiclist_s = musiclist_o.copy()
self.multiworld.random.shuffle(musiclist_s) self.multiworld.random.shuffle(musiclist_s)
musiclist_o.extend(range(47, 78))
musiclist_s.extend(range(47, 78))
if self.multiworld.sadx_music[self.player].value == 1:
musiclist_s = [x+100 for x in musiclist_s]
elif self.multiworld.sadx_music[self.player].value == 2:
for i in range(len(musiclist_s)):
if self.multiworld.random.randint(0,1):
musiclist_s[i] += 100
self.music_map = dict(zip(musiclist_o, musiclist_s)) self.music_map = dict(zip(musiclist_o, musiclist_s))
elif self.multiworld.music_shuffle[self.player] == "full": elif self.multiworld.music_shuffle[self.player] == "full":
musiclist_o = list(range(0, 78)) musiclist_o = list(range(0, 78))
musiclist_s = musiclist_o.copy() musiclist_s = musiclist_o.copy()
self.multiworld.random.shuffle(musiclist_s) self.multiworld.random.shuffle(musiclist_s)
if self.multiworld.sadx_music[self.player].value == 1:
musiclist_s = [x+100 for x in musiclist_s]
elif self.multiworld.sadx_music[self.player].value == 2:
for i in range(len(musiclist_s)):
if self.multiworld.random.randint(0,1):
musiclist_s[i] += 100
self.music_map = dict(zip(musiclist_o, musiclist_s))
elif self.multiworld.music_shuffle[self.player] == "singularity":
musiclist_o = list(range(0, 78))
musiclist_s = [self.multiworld.random.choice(musiclist_o)] * len(musiclist_o)
if self.multiworld.sadx_music[self.player].value == 1:
musiclist_s = [x+100 for x in musiclist_s]
elif self.multiworld.sadx_music[self.player].value == 2:
if self.multiworld.random.randint(0,1):
musiclist_s = [x+100 for x in musiclist_s]
self.music_map = dict(zip(musiclist_o, musiclist_s)) self.music_map = dict(zip(musiclist_o, musiclist_s))
else: else:
self.music_map = dict() musiclist_o = list(range(0, 78))
musiclist_s = musiclist_o.copy()
if self.multiworld.sadx_music[self.player].value == 1:
musiclist_s = [x+100 for x in musiclist_s]
elif self.multiworld.sadx_music[self.player].value == 2:
for i in range(len(musiclist_s)):
if self.multiworld.random.randint(0,1):
musiclist_s[i] += 100
self.music_map = dict(zip(musiclist_o, musiclist_s))
def create_regions(self): def create_regions(self):
self.location_table = setup_locations(self.multiworld, self.player) self.mission_map = get_mission_table(self.multiworld, self.player)
self.mission_count_map = get_mission_count_table(self.multiworld, self.player)
self.location_table = setup_locations(self.multiworld, self.player, self.mission_map, self.mission_count_map)
create_regions(self.multiworld, self.player, self.location_table) create_regions(self.multiworld, self.player, self.location_table)
def create_item(self, name: str, force_non_progression=False) -> Item: def create_item(self, name: str, force_non_progression=False) -> Item:
@ -268,18 +334,52 @@ class SA2BWorld(World):
return created_item return created_item
def get_filler_item_name(self) -> str:
self.multiworld.random.choice(junk_table.keys())
def set_rules(self): def set_rules(self):
set_rules(self.multiworld, self.player, self.gate_bosses) set_rules(self.multiworld, self.player, self.gate_bosses, self.mission_map, self.mission_count_map)
def write_spoiler(self, spoiler_handle: typing.TextIO): def write_spoiler(self, spoiler_handle: typing.TextIO):
spoiler_handle.write("\n") if self.multiworld.number_of_level_gates[self.player].value > 0:
header_text = "Sonic Adventure 2 Bosses for {}:\n" spoiler_handle.write("\n")
header_text = header_text.format(self.multiworld.player_name[self.player]) header_text = "Sonic Adventure 2 Bosses for {}:\n"
spoiler_handle.write(header_text) header_text = header_text.format(self.multiworld.player_name[self.player])
for x in range(len(self.gate_bosses.values())): spoiler_handle.write(header_text)
text = "Gate {0} Boss: {1}\n" for x in range(len(self.gate_bosses.values())):
text = text.format((x + 1), get_boss_name(self.gate_bosses[x + 1])) text = "Gate {0} Boss: {1}\n"
spoiler_handle.writelines(text) text = text.format((x + 1), get_boss_name(self.gate_bosses[x + 1]))
spoiler_handle.writelines(text)
def extend_hint_information(self, hint_data: typing.Dict[int, typing.Dict[int, str]]):
gate_names = [
LocationName.gate_0_region,
LocationName.gate_1_region,
LocationName.gate_2_region,
LocationName.gate_3_region,
LocationName.gate_4_region,
LocationName.gate_5_region,
]
no_hint_region_names = [
LocationName.cannon_core_region,
LocationName.chao_garden_beginner_region,
LocationName.chao_garden_intermediate_region,
LocationName.chao_garden_expert_region,
]
er_hint_data = {}
for i in range(self.multiworld.number_of_level_gates[self.player].value + 1):
gate_name = gate_names[i]
gate_region = self.multiworld.get_region(gate_name, self.player)
if not gate_region:
continue
for exit in gate_region.exits:
if exit.connected_region.name in gate_names or exit.connected_region.name in no_hint_region_names:
continue
level_region = exit.connected_region
for location in level_region.locations:
er_hint_data[location.address] = gate_name
hint_data[self.player] = er_hint_data
@classmethod @classmethod
def stage_fill_hook(cls, world, progitempool, usefulitempool, filleritempool, fill_locations): def stage_fill_hook(cls, world, progitempool, usefulitempool, filleritempool, fill_locations):

View File

@ -6,15 +6,15 @@ The [player settings page for this game](../player-settings) contains all the op
## What does randomization do to this game? ## What does randomization do to this game?
The randomizer shuffles emblems and upgrade items into the AP item pool. The story mode is disabled, but stage select is available from the start. Levels can be locked behind gates requiring a certain number of emblems and a boss fight to unlock. Cannons Core will be locked behind a percentage of all available emblems, and completing Cannons Core will unlock the Biolizard boss. Progress towards unlocking Cannons Core and the next stage gate will be displayed on the Stage Select screen. The randomizer shuffles emblems and upgrade items into the AP item pool. The story mode is disabled, but stage select is available from the start. Levels can be locked behind gates requiring a certain number of emblems and a boss fight to unlock. Cannon's Core will be locked behind a percentage of all available emblems, and completing Cannon's Core will unlock the Biolizard boss if Biolizard is the goal. If the emerald hunt goal is selected, collecting all seven Chaos Emeralds will unlock Green Hill Zone. Progress towards unlocking Cannon's Core and the next stage gate will be displayed on the Stage Select screen.
## What is the goal of Sonic Adventure 2: Battle when randomized? ## What is the goal of Sonic Adventure 2: Battle when randomized?
The goal is to unlock and complete Cannons Core Mission 1, then complete the Biolizard boss fight. If the Biolizard goal is selected, the objective is to unlock and complete the required number of Cannon's Core Missions, then complete the Biolizard boss fight. If the Emerald Hunt goal is selected, the objective is to find the seven Chaos Emeralds then complete Green Hill Zone and optionally default Final Hazard.
## What items and locations get shuffled? ## What items and locations get shuffled?
All 30 story stages leading up to Cannons Core will be shuffled and can be optionally placed behind emblem requirement gates. Chao Garden emblems can optionally be added to the randomizer. All emblems from the selected mission range and all 28 character upgrade items get shuffled. At most 180 emblems will be added to the item pool, after which remaining items added will be random collectables (rings, shields, etc). Traps can also be optionally included. All 30 story stages leading up to Cannon's Core will be shuffled and can be optionally placed behind emblem requirement gates. Mission order can be shuffled for each stage. Chao keys, animal pipes, hidden whistle spots, and gold beetles can be added as additional locations to check in each stage. Chao Garden emblems can optionally be added to the randomizer. All emblems from the selected mission range and all 28 character upgrade items get shuffled. At most 180 emblems will be added to the item pool, after which remaining items added will be random collectables (rings, shields, etc). Traps can also be optionally included.
## Which items can be in another player's world? ## Which items can be in another player's world?
@ -22,11 +22,11 @@ Any shuffled item can be in other players' worlds.
## What does another world's item look like in Sonic Adventure 2: Battle ## What does another world's item look like in Sonic Adventure 2: Battle
Emblems have no visualization in the randomizer and items all retain their original appearance. You won't know if an item belongs to another player until you collect. Emblems have no visualization in the randomizer and items all retain their original appearance. Chao Keys will appear as an Archipelago logo even if the keysanity option is disabled. Despite the appearance, they will only count as a check if the keysanity option is enabled. You won't know if an item belongs to another player until you collect.
## When the player receives an emblem or item, what happens? ## When the player receives an emblem or item, what happens?
When the player collects an emblem or item, text will appear on screen to indicate who the item was for and what the item was. When collecting items in a level, the orignal item collection text will display and will likely not be correct. When the player collects an emblem or item, text will appear on screen to indicate who the item was for and what the item was. When collecting an upgrade location, the orignal item collection text will display and will likely not be correct.
## How can I get started? ## How can I get started?

View File

@ -54,6 +54,14 @@ Some additional settings related to the Archipelago messages in game can be adju
- Message Display Duration: This dictates how long Archipelago messages are displayed on screen (in seconds). - Message Display Duration: This dictates how long Archipelago messages are displayed on screen (in seconds).
- Message Font Size: The is the size of the font used to display the messages from Archipelago. - Message Font Size: The is the size of the font used to display the messages from Archipelago.
If you wish to use the `SADX Music` option of the Randomizer, you must own a copy of `Sonic Adventure DX` on Steam, and follow these steps:
1. Find the folder on your PC where `Sonic Adventure DX` is installed.
2. Enter the `SoundData` folder in the `Sonic Adventure DX` installation folder, and copy the `bgm` folder.
3. Paste the `bgm` folder into the `ADX` folder which exists within the `gd_PC` folder in your `SA2B_Archipelago` mod folder.
## Troubleshooting ## Troubleshooting
- "The following mods didn't load correctly: SA2B_Archipelago: DLL error - The specified module could not be found." - "The following mods didn't load correctly: SA2B_Archipelago: DLL error - The specified module could not be found."
@ -92,6 +100,12 @@ Some additional settings related to the Archipelago messages in game can be adju
- No resolution options in the Launcher.exe. - No resolution options in the Launcher.exe.
- In the `Graphics device` dropdown, select the device and display you plan to run the game on. The `Resolution` dropdown should populate once a graphics device is selected. - In the `Graphics device` dropdown, select the device and display you plan to run the game on. The `Resolution` dropdown should populate once a graphics device is selected.
- No music is playing in the game.
- If you enabled an `SADX Music` option, then most likely the music data was not copied properly into the mod folder (See Additional Options for instructions).
- Mission 1 is missing a texture in the stage select UI.
- Most likely another mod is conflicting and overwriting the texture pack. It is recommeded to have the SA2B Archipelago mod load last in the mod loader.
## Save File Safeguard (Advanced Option) ## Save File Safeguard (Advanced Option)