SA2B: v2.1 Content Update (#1563)

Changelog:

Features:
- New goal
  - Grand Prix
    - Complete all of the Kart Races to win!
- New optional Location Checks
  - Omosanity (Activating Omochao)
  - Kart Race Mode
- Ring Loss option
  - `Classic` - lose all rings on hit
  - `Modern` - lose 20 rings on hit
  - `OHKO` - instantly die on hit, regardless of ring count (shields still protect you)
- New Trap
  - Pong Trap

Quality of Life:
- SA2B is now distributed as an `.apworld`
- Maximum possible number of Emblems in item pool is increased from 180 to 250
- An indicator now shows on the Stage Select screen when `Cannon's Core` is available
- Certain traps (`Exposition` and `Pong`) are now possible to receive on `Route 101` and `Route 280`
- Certain traps (`Confusion`, `Chaos Control`, `Exposition` and `Pong`) are now possible to receive on `FinalHazard`

Bug Fixes:
- Actually swap Intermediate and Expert Chao Races correctly
- Don't always grant double score for killing Gold Beetles anymore
- Ensure upgrades are applied properly, even when received while dying
- Fix the Message Queue getting disordered when receiving many messages in quick succession
- Fix Logic errors
  - `City Escape - 3` (Hard Logic) now requires no upgrades
  - `Mission Street - Pipe 2` (Hard Logic) now requires no upgrades
  - `Crazy Gadget - Pipe 3` (Hard Logic) now requires no upgrades
  - `Egg Quarters - 3` (Hard Logic) now requires only `Rouge - Mystic Melody`
  - `Mad Space - 5` (Hard Logic) now requires no upgrades

Co-authored-by: RaspberrySpaceJam <tyler.summers@gmail.com>
This commit is contained in:
PoryGone 2023-03-21 16:26:13 -04:00 committed by GitHub
parent 2fb9176511
commit 21a3c74783
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1394 additions and 221 deletions

View File

@ -49,6 +49,7 @@ apworlds: set = {
"Subnautica",
"Factorio",
"Rogue Legacy",
"Sonic Adventure 2 Battle",
"Donkey Kong Country 3",
"Super Mario World",
"Stardew Valley",

View File

@ -79,6 +79,8 @@ trap_table = {
ItemName.gravity_trap: ItemData(0xFF0034, False, True),
ItemName.exposition_trap: ItemData(0xFF0035, False, True),
#ItemName.darkness_trap: ItemData(0xFF0036, False, True),
ItemName.pong_trap: ItemData(0xFF0050, False, True),
}
emeralds_table = {

View File

@ -504,6 +504,235 @@ beetle_location_table = {
LocationName.cannon_core_beetle: 0xFF061E,
}
omochao_location_table = {
LocationName.city_escape_omo_1: 0xFF0800,
LocationName.wild_canyon_omo_1: 0xFF0801,
LocationName.prison_lane_omo_1: 0xFF0802,
LocationName.metal_harbor_omo_1: 0xFF0803,
LocationName.pumpkin_hill_omo_1: 0xFF0805,
LocationName.mission_street_omo_1: 0xFF0806,
LocationName.aquatic_mine_omo_1: 0xFF0807,
LocationName.hidden_base_omo_1: 0xFF0809,
LocationName.pyramid_cave_omo_1: 0xFF080A,
LocationName.death_chamber_omo_1: 0xFF080B,
LocationName.eternal_engine_omo_1: 0xFF080C,
LocationName.meteor_herd_omo_1: 0xFF080D,
LocationName.crazy_gadget_omo_1: 0xFF080E,
LocationName.final_rush_omo_1: 0xFF080F,
LocationName.iron_gate_omo_1: 0xFF0810,
LocationName.dry_lagoon_omo_1: 0xFF0811,
LocationName.sand_ocean_omo_1: 0xFF0812,
LocationName.radical_highway_omo_1: 0xFF0813,
LocationName.egg_quarters_omo_1: 0xFF0814,
LocationName.lost_colony_omo_1: 0xFF0815,
LocationName.weapons_bed_omo_1: 0xFF0816,
LocationName.security_hall_omo_1: 0xFF0817,
LocationName.white_jungle_omo_1: 0xFF0818,
LocationName.mad_space_omo_1: 0xFF081B,
LocationName.cosmic_wall_omo_1: 0xFF081C,
LocationName.final_chase_omo_1: 0xFF081D,
LocationName.cannon_core_omo_1: 0xFF081E,
LocationName.city_escape_omo_2: 0xFF0820,
LocationName.wild_canyon_omo_2: 0xFF0821,
LocationName.prison_lane_omo_2: 0xFF0822,
LocationName.metal_harbor_omo_2: 0xFF0823,
LocationName.pumpkin_hill_omo_2: 0xFF0825,
LocationName.mission_street_omo_2: 0xFF0826,
LocationName.aquatic_mine_omo_2: 0xFF0827,
LocationName.hidden_base_omo_2: 0xFF0829,
LocationName.pyramid_cave_omo_2: 0xFF082A,
LocationName.death_chamber_omo_2: 0xFF082B,
LocationName.eternal_engine_omo_2: 0xFF082C,
LocationName.meteor_herd_omo_2: 0xFF082D,
LocationName.crazy_gadget_omo_2: 0xFF082E,
LocationName.final_rush_omo_2: 0xFF082F,
LocationName.iron_gate_omo_2: 0xFF0830,
LocationName.dry_lagoon_omo_2: 0xFF0831,
LocationName.sand_ocean_omo_2: 0xFF0832,
LocationName.radical_highway_omo_2: 0xFF0833,
LocationName.egg_quarters_omo_2: 0xFF0834,
LocationName.lost_colony_omo_2: 0xFF0835,
LocationName.weapons_bed_omo_2: 0xFF0836,
LocationName.security_hall_omo_2: 0xFF0837,
LocationName.white_jungle_omo_2: 0xFF0838,
LocationName.mad_space_omo_2: 0xFF083B,
LocationName.cannon_core_omo_2: 0xFF083E,
LocationName.city_escape_omo_3: 0xFF0840,
LocationName.wild_canyon_omo_3: 0xFF0841,
LocationName.prison_lane_omo_3: 0xFF0842,
LocationName.metal_harbor_omo_3: 0xFF0843,
LocationName.pumpkin_hill_omo_3: 0xFF0845,
LocationName.mission_street_omo_3: 0xFF0846,
LocationName.aquatic_mine_omo_3: 0xFF0847,
LocationName.hidden_base_omo_3: 0xFF0849,
LocationName.pyramid_cave_omo_3: 0xFF084A,
LocationName.death_chamber_omo_3: 0xFF084B,
LocationName.eternal_engine_omo_3: 0xFF084C,
LocationName.meteor_herd_omo_3: 0xFF084D,
LocationName.crazy_gadget_omo_3: 0xFF084E,
LocationName.final_rush_omo_3: 0xFF084F,
LocationName.iron_gate_omo_3: 0xFF0850,
LocationName.dry_lagoon_omo_3: 0xFF0851,
LocationName.radical_highway_omo_3: 0xFF0853,
LocationName.egg_quarters_omo_3: 0xFF0854,
LocationName.lost_colony_omo_3: 0xFF0855,
LocationName.weapons_bed_omo_3: 0xFF0856,
LocationName.security_hall_omo_3: 0xFF0857,
LocationName.white_jungle_omo_3: 0xFF0858,
LocationName.mad_space_omo_3: 0xFF085B,
LocationName.cannon_core_omo_3: 0xFF085E,
LocationName.city_escape_omo_4: 0xFF0860,
LocationName.wild_canyon_omo_4: 0xFF0861,
LocationName.prison_lane_omo_4: 0xFF0862,
LocationName.metal_harbor_omo_4: 0xFF0863,
LocationName.pumpkin_hill_omo_4: 0xFF0865,
LocationName.mission_street_omo_4: 0xFF0866,
LocationName.aquatic_mine_omo_4: 0xFF0867,
LocationName.hidden_base_omo_4: 0xFF0869,
LocationName.pyramid_cave_omo_4: 0xFF086A,
LocationName.death_chamber_omo_4: 0xFF086B,
LocationName.eternal_engine_omo_4: 0xFF086C,
LocationName.crazy_gadget_omo_4: 0xFF086E,
LocationName.iron_gate_omo_4: 0xFF0870,
LocationName.dry_lagoon_omo_4: 0xFF0871,
LocationName.radical_highway_omo_4: 0xFF0873,
LocationName.egg_quarters_omo_4: 0xFF0874,
LocationName.lost_colony_omo_4: 0xFF0875,
LocationName.security_hall_omo_4: 0xFF0877,
LocationName.white_jungle_omo_4: 0xFF0878,
LocationName.mad_space_omo_4: 0xFF087B,
LocationName.cannon_core_omo_4: 0xFF087E,
LocationName.city_escape_omo_5: 0xFF0880,
LocationName.wild_canyon_omo_5: 0xFF0881,
LocationName.prison_lane_omo_5: 0xFF0882,
LocationName.metal_harbor_omo_5: 0xFF0883,
LocationName.pumpkin_hill_omo_5: 0xFF0885,
LocationName.mission_street_omo_5: 0xFF0886,
LocationName.aquatic_mine_omo_5: 0xFF0887,
LocationName.death_chamber_omo_5: 0xFF088B,
LocationName.eternal_engine_omo_5: 0xFF088C,
LocationName.crazy_gadget_omo_5: 0xFF088E,
LocationName.iron_gate_omo_5: 0xFF0890,
LocationName.dry_lagoon_omo_5: 0xFF0891,
LocationName.radical_highway_omo_5: 0xFF0893,
LocationName.egg_quarters_omo_5: 0xFF0894,
LocationName.lost_colony_omo_5: 0xFF0895,
LocationName.security_hall_omo_5: 0xFF0897,
LocationName.white_jungle_omo_5: 0xFF0898,
LocationName.mad_space_omo_5: 0xFF089B,
LocationName.cannon_core_omo_5: 0xFF089E,
LocationName.city_escape_omo_6: 0xFF08A0,
LocationName.wild_canyon_omo_6: 0xFF08A1,
LocationName.prison_lane_omo_6: 0xFF08A2,
LocationName.pumpkin_hill_omo_6: 0xFF08A5,
LocationName.mission_street_omo_6: 0xFF08A6,
LocationName.aquatic_mine_omo_6: 0xFF08A7,
LocationName.death_chamber_omo_6: 0xFF08AB,
LocationName.eternal_engine_omo_6: 0xFF08AC,
LocationName.crazy_gadget_omo_6: 0xFF08AE,
LocationName.iron_gate_omo_6: 0xFF08B0,
LocationName.dry_lagoon_omo_6: 0xFF08B1,
LocationName.radical_highway_omo_6: 0xFF08B3,
LocationName.egg_quarters_omo_6: 0xFF08B4,
LocationName.lost_colony_omo_6: 0xFF08B5,
LocationName.security_hall_omo_6: 0xFF08B7,
LocationName.cannon_core_omo_6: 0xFF08BE,
LocationName.city_escape_omo_7: 0xFF08C0,
LocationName.wild_canyon_omo_7: 0xFF08C1,
LocationName.prison_lane_omo_7: 0xFF08C2,
LocationName.pumpkin_hill_omo_7: 0xFF08C5,
LocationName.mission_street_omo_7: 0xFF08C6,
LocationName.aquatic_mine_omo_7: 0xFF08C7,
LocationName.death_chamber_omo_7: 0xFF08CB,
LocationName.eternal_engine_omo_7: 0xFF08CC,
LocationName.crazy_gadget_omo_7: 0xFF08CE,
LocationName.dry_lagoon_omo_7: 0xFF08D1,
LocationName.radical_highway_omo_7: 0xFF08D3,
LocationName.egg_quarters_omo_7: 0xFF08D4,
LocationName.lost_colony_omo_7: 0xFF08D5,
LocationName.security_hall_omo_7: 0xFF08D7,
LocationName.cannon_core_omo_7: 0xFF08DE,
LocationName.city_escape_omo_8: 0xFF08E0,
LocationName.wild_canyon_omo_8: 0xFF08E1,
LocationName.prison_lane_omo_8: 0xFF08E2,
LocationName.pumpkin_hill_omo_8: 0xFF08E5,
LocationName.mission_street_omo_8: 0xFF08E6,
LocationName.death_chamber_omo_8: 0xFF08EB,
LocationName.eternal_engine_omo_8: 0xFF08EC,
LocationName.crazy_gadget_omo_8: 0xFF08EE,
LocationName.dry_lagoon_omo_8: 0xFF08F1,
LocationName.radical_highway_omo_8: 0xFF08F3,
LocationName.lost_colony_omo_8: 0xFF08F5,
LocationName.security_hall_omo_8: 0xFF08F7,
LocationName.cannon_core_omo_8: 0xFF08FE,
LocationName.city_escape_omo_9: 0xFF0900,
LocationName.wild_canyon_omo_9: 0xFF0901,
LocationName.prison_lane_omo_9: 0xFF0902,
LocationName.pumpkin_hill_omo_9: 0xFF0905,
LocationName.death_chamber_omo_9: 0xFF090B,
LocationName.eternal_engine_omo_9: 0xFF090C,
LocationName.crazy_gadget_omo_9: 0xFF090E,
LocationName.dry_lagoon_omo_9: 0xFF0911,
LocationName.security_hall_omo_9: 0xFF0917,
LocationName.cannon_core_omo_9: 0xFF091E,
LocationName.city_escape_omo_10: 0xFF0920,
LocationName.wild_canyon_omo_10: 0xFF0921,
LocationName.prison_lane_omo_10: 0xFF0922,
LocationName.pumpkin_hill_omo_10: 0xFF0925,
LocationName.eternal_engine_omo_10: 0xFF092C,
LocationName.crazy_gadget_omo_10: 0xFF092E,
LocationName.dry_lagoon_omo_10: 0xFF0931,
LocationName.security_hall_omo_10: 0xFF0937,
LocationName.city_escape_omo_11: 0xFF0940,
LocationName.pumpkin_hill_omo_11: 0xFF0945,
LocationName.eternal_engine_omo_11: 0xFF094C,
LocationName.crazy_gadget_omo_11: 0xFF094E,
LocationName.dry_lagoon_omo_11: 0xFF0951,
LocationName.security_hall_omo_11: 0xFF0957,
LocationName.city_escape_omo_12: 0xFF0960,
LocationName.eternal_engine_omo_12: 0xFF096C,
LocationName.crazy_gadget_omo_12: 0xFF096E,
LocationName.dry_lagoon_omo_12: 0xFF0971,
LocationName.security_hall_omo_12: 0xFF0977,
LocationName.city_escape_omo_13: 0xFF0980,
LocationName.crazy_gadget_omo_13: 0xFF098E,
LocationName.city_escape_omo_14: 0xFF09A0,
}
boss_gate_location_table = {
LocationName.gate_1_boss: 0xFF0100,
LocationName.gate_2_boss: 0xFF0101,
@ -530,6 +759,33 @@ chao_garden_beginner_location_table = {
}
chao_garden_intermediate_location_table = {
LocationName.chao_race_challenge_1: 0xFF022A,
LocationName.chao_race_challenge_2: 0xFF022B,
LocationName.chao_race_challenge_3: 0xFF022C,
LocationName.chao_race_challenge_4: 0xFF022D,
LocationName.chao_race_challenge_5: 0xFF022E,
LocationName.chao_race_challenge_6: 0xFF022F,
LocationName.chao_race_challenge_7: 0xFF0230,
LocationName.chao_race_challenge_8: 0xFF0231,
LocationName.chao_race_challenge_9: 0xFF0232,
LocationName.chao_race_challenge_10: 0xFF0233,
LocationName.chao_race_challenge_11: 0xFF0234,
LocationName.chao_race_challenge_12: 0xFF0235,
LocationName.chao_race_hero_1: 0xFF0236,
LocationName.chao_race_hero_2: 0xFF0237,
LocationName.chao_race_hero_3: 0xFF0238,
LocationName.chao_race_hero_4: 0xFF0239,
LocationName.chao_race_dark_1: 0xFF023A,
LocationName.chao_race_dark_2: 0xFF023B,
LocationName.chao_race_dark_3: 0xFF023C,
LocationName.chao_race_dark_4: 0xFF023D,
LocationName.chao_standard_karate: 0xFF0301,
}
chao_garden_expert_location_table = {
LocationName.chao_race_aquamarine_1: 0xFF020C,
LocationName.chao_race_aquamarine_2: 0xFF020D,
LocationName.chao_race_aquamarine_3: 0xFF020E,
@ -561,37 +817,43 @@ chao_garden_intermediate_location_table = {
LocationName.chao_race_diamond_4: 0xFF0228,
LocationName.chao_race_diamond_5: 0xFF0229,
LocationName.chao_standard_karate: 0xFF0301,
}
chao_garden_expert_location_table = {
LocationName.chao_race_challenge_1: 0xFF022A,
LocationName.chao_race_challenge_2: 0xFF022B,
LocationName.chao_race_challenge_3: 0xFF022C,
LocationName.chao_race_challenge_4: 0xFF022D,
LocationName.chao_race_challenge_5: 0xFF022E,
LocationName.chao_race_challenge_6: 0xFF022F,
LocationName.chao_race_challenge_7: 0xFF0230,
LocationName.chao_race_challenge_8: 0xFF0231,
LocationName.chao_race_challenge_9: 0xFF0232,
LocationName.chao_race_challenge_10: 0xFF0233,
LocationName.chao_race_challenge_11: 0xFF0234,
LocationName.chao_race_challenge_12: 0xFF0235,
LocationName.chao_race_hero_1: 0xFF0236,
LocationName.chao_race_hero_2: 0xFF0237,
LocationName.chao_race_hero_3: 0xFF0238,
LocationName.chao_race_hero_4: 0xFF0239,
LocationName.chao_race_dark_1: 0xFF023A,
LocationName.chao_race_dark_2: 0xFF023B,
LocationName.chao_race_dark_3: 0xFF023C,
LocationName.chao_race_dark_4: 0xFF023D,
LocationName.chao_expert_karate: 0xFF0302,
LocationName.chao_super_karate: 0xFF0303,
}
kart_race_beginner_location_table = {
LocationName.kart_race_beginner_sonic: 0xFF0A00,
LocationName.kart_race_beginner_tails: 0xFF0A01,
LocationName.kart_race_beginner_knuckles: 0xFF0A02,
LocationName.kart_race_beginner_shadow: 0xFF0A03,
LocationName.kart_race_beginner_eggman: 0xFF0A04,
LocationName.kart_race_beginner_rouge: 0xFF0A05,
}
kart_race_standard_location_table = {
LocationName.kart_race_standard_sonic: 0xFF0A06,
LocationName.kart_race_standard_tails: 0xFF0A07,
LocationName.kart_race_standard_knuckles: 0xFF0A08,
LocationName.kart_race_standard_shadow: 0xFF0A09,
LocationName.kart_race_standard_eggman: 0xFF0A0A,
LocationName.kart_race_standard_rouge: 0xFF0A0B,
}
kart_race_expert_location_table = {
LocationName.kart_race_expert_sonic: 0xFF0A0C,
LocationName.kart_race_expert_tails: 0xFF0A0D,
LocationName.kart_race_expert_knuckles: 0xFF0A0E,
LocationName.kart_race_expert_shadow: 0xFF0A0F,
LocationName.kart_race_expert_eggman: 0xFF0A10,
LocationName.kart_race_expert_rouge: 0xFF0A11,
}
kart_race_mini_location_table = {
LocationName.kart_race_beginner: 0xFF0A12,
LocationName.kart_race_standard: 0xFF0A13,
LocationName.kart_race_expert: 0xFF0A14,
}
green_hill_location_table = {
LocationName.green_hill: 0xFF001F,
}
@ -605,6 +867,10 @@ final_boss_location_table = {
LocationName.finalhazard: 0xFF005F,
}
grand_prix_location_table = {
LocationName.grand_prix: 0xFF007F,
}
all_locations = {
**mission_location_table,
**upgrade_location_table,
@ -613,12 +879,18 @@ all_locations = {
**pipe_location_table,
**hidden_whistle_location_table,
**beetle_location_table,
**omochao_location_table,
**chao_garden_beginner_location_table,
**chao_garden_intermediate_location_table,
**chao_garden_expert_location_table,
**kart_race_beginner_location_table,
**kart_race_standard_location_table,
**kart_race_expert_location_table,
**kart_race_mini_location_table,
**green_hill_location_table,
**green_hill_chao_location_table,
**final_boss_location_table,
**grand_prix_location_table,
}
boss_gate_set = [
@ -665,62 +937,80 @@ def setup_locations(world: MultiWorld, player: int, mission_map: typing.Dict[int
location_table = {}
chao_location_table = {}
if world.goal[player] == 3:
if world.kart_race_checks[player] == 2:
location_table.update({**kart_race_beginner_location_table})
location_table.update({**kart_race_standard_location_table})
location_table.update({**kart_race_expert_location_table})
elif world.kart_race_checks[player] == 1:
location_table.update({**kart_race_mini_location_table})
location_table.update({**grand_prix_location_table})
else:
for i in range(31):
mission_count = mission_count_map[i]
mission_order: typing.List[int] = mission_orders[mission_map[i]]
stage_prefix: str = stage_name_prefixes[i]
for i in range(31):
mission_count = mission_count_map[i]
mission_order: typing.List[int] = mission_orders[mission_map[i]]
stage_prefix: str = stage_name_prefixes[i]
for j in range(mission_count):
mission_number = mission_order[j]
location_name: str = stage_prefix + str(mission_number)
location_table[location_name] = mission_location_table[location_name]
for j in range(mission_count):
mission_number = mission_order[j]
location_name: str = stage_prefix + str(mission_number)
location_table[location_name] = mission_location_table[location_name]
location_table.update({**upgrade_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})
location_table.update({**upgrade_location_table})
if world.keysanity[player]:
location_table.update({**green_hill_chao_location_table})
location_table.update({**chao_key_location_table})
if world.chao_garden_difficulty[player].value >= 1:
chao_location_table.update({**chao_garden_beginner_location_table})
if world.chao_garden_difficulty[player].value >= 2:
chao_location_table.update({**chao_garden_intermediate_location_table})
if world.chao_garden_difficulty[player].value >= 3:
chao_location_table.update({**chao_garden_expert_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})
for key, value in chao_location_table.items():
if key in chao_karate_set:
if world.include_chao_karate[player]:
if world.beetlesanity[player]:
location_table.update({**beetle_location_table})
if world.omosanity[player]:
location_table.update({**omochao_location_table})
if world.kart_race_checks[player] == 2:
location_table.update({**kart_race_beginner_location_table})
location_table.update({**kart_race_standard_location_table})
location_table.update({**kart_race_expert_location_table})
elif world.kart_race_checks[player] == 1:
location_table.update({**kart_race_mini_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:
chao_location_table.update({**chao_garden_beginner_location_table})
if world.chao_garden_difficulty[player].value >= 2:
chao_location_table.update({**chao_garden_intermediate_location_table})
if world.chao_garden_difficulty[player].value >= 3:
chao_location_table.update({**chao_garden_expert_location_table})
for key, value in chao_location_table.items():
if key in chao_karate_set:
if world.include_chao_karate[player]:
location_table[key] = value
elif key not in chao_race_prize_set:
if world.chao_race_checks[player] == "all":
location_table[key] = value
else:
location_table[key] = value
elif key not in chao_race_prize_set:
if world.chao_race_checks[player] == "all":
location_table[key] = value
else:
location_table[key] = value
for x in range(len(boss_gate_set)):
if x < world.number_of_level_gates[player].value:
location_table[boss_gate_set[x]] = boss_gate_location_table[boss_gate_set[x]]
for x in range(len(boss_gate_set)):
if x < world.number_of_level_gates[player].value:
location_table[boss_gate_set[x]] = boss_gate_location_table[boss_gate_set[x]]
return location_table

View File

@ -194,48 +194,52 @@ stage_name_prefixes: typing.List[str] = [
]
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
if multiworld.goal[player] == 3:
for level in range(31):
mission_count_table[level] = 0
else:
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
]
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
@ -243,73 +247,77 @@ def get_mission_count_table(multiworld: MultiWorld, player: int):
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]
if multiworld.goal[player] == 3:
for level in range(31):
mission_table[level] = 0
else:
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
# Add included missions
for i in range(2,6):
if i not in level_chosen_missions:
level_chosen_missions.append(i)
if getattr(multiworld, "speed_mission_" + str(i), None)[player]:
speed_active_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
if getattr(multiworld, "mech_mission_" + str(i), None)[player]:
mech_active_missions.append(i)
mission_table[level] = level_mission_index
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, M3, 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

View File

@ -51,6 +51,7 @@ tiny_trap = "Tiny Trap"
gravity_trap = "Gravity Trap"
exposition_trap = "Exposition Trap"
darkness_trap = "Darkness Trap"
pong_trap = "Pong Trap"
white_emerald = "White Chaos Emerald"
red_emerald = "Red Chaos Emerald"

View File

@ -16,6 +16,20 @@ city_escape_hidden_2 = "City Escape - Hidden 2"
city_escape_hidden_3 = "City Escape - Hidden 3"
city_escape_hidden_4 = "City Escape - Hidden 4"
city_escape_hidden_5 = "City Escape - Hidden 5"
city_escape_omo_1 = "City Escape - Omochao 1"
city_escape_omo_2 = "City Escape - Omochao 2"
city_escape_omo_3 = "City Escape - Omochao 3"
city_escape_omo_4 = "City Escape - Omochao 4"
city_escape_omo_5 = "City Escape - Omochao 5"
city_escape_omo_6 = "City Escape - Omochao 6"
city_escape_omo_7 = "City Escape - Omochao 7"
city_escape_omo_8 = "City Escape - Omochao 8"
city_escape_omo_9 = "City Escape - Omochao 9"
city_escape_omo_10 = "City Escape - Omochao 10"
city_escape_omo_11 = "City Escape - Omochao 11"
city_escape_omo_12 = "City Escape - Omochao 12"
city_escape_omo_13 = "City Escape - Omochao 13"
city_escape_omo_14 = "City Escape - Omochao 14"
city_escape_beetle = "City Escape - Gold Beetle"
city_escape_upgrade = "City Escape - Upgrade"
metal_harbor_1 = "Metal Harbor - 1"
@ -27,6 +41,11 @@ metal_harbor_chao_1 = "Metal Harbor - Chao Key 1"
metal_harbor_chao_2 = "Metal Harbor - Chao Key 2"
metal_harbor_chao_3 = "Metal Harbor - Chao Key 3"
metal_harbor_pipe_1 = "Metal Harbor - Pipe 1"
metal_harbor_omo_1 = "Metal Harbor - Omochao 1"
metal_harbor_omo_2 = "Metal Harbor - Omochao 2"
metal_harbor_omo_3 = "Metal Harbor - Omochao 3"
metal_harbor_omo_4 = "Metal Harbor - Omochao 4"
metal_harbor_omo_5 = "Metal Harbor - Omochao 5"
metal_harbor_beetle = "Metal Harbor - Gold Beetle"
metal_harbor_upgrade = "Metal Harbor - Upgrade"
green_forest_1 = "Green Forest - 1"
@ -57,6 +76,10 @@ 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_omo_1 = "Pyramid Cave - Omochao 1"
pyramid_cave_omo_2 = "Pyramid Cave - Omochao 2"
pyramid_cave_omo_3 = "Pyramid Cave - Omochao 3"
pyramid_cave_omo_4 = "Pyramid Cave - Omochao 4"
pyramid_cave_beetle = "Pyramid Cave - Gold Beetle"
pyramid_cave_upgrade = "Pyramid Cave - Upgrade"
crazy_gadget_1 = "Crazy Gadget - 1"
@ -72,6 +95,19 @@ 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_omo_1 = "Crazy Gadget - Omochao 1"
crazy_gadget_omo_2 = "Crazy Gadget - Omochao 2"
crazy_gadget_omo_3 = "Crazy Gadget - Omochao 3"
crazy_gadget_omo_4 = "Crazy Gadget - Omochao 4"
crazy_gadget_omo_5 = "Crazy Gadget - Omochao 5"
crazy_gadget_omo_6 = "Crazy Gadget - Omochao 6"
crazy_gadget_omo_7 = "Crazy Gadget - Omochao 7"
crazy_gadget_omo_8 = "Crazy Gadget - Omochao 8"
crazy_gadget_omo_9 = "Crazy Gadget - Omochao 9"
crazy_gadget_omo_10 = "Crazy Gadget - Omochao 10"
crazy_gadget_omo_11 = "Crazy Gadget - Omochao 11"
crazy_gadget_omo_12 = "Crazy Gadget - Omochao 12"
crazy_gadget_omo_13 = "Crazy Gadget - Omochao 13"
crazy_gadget_beetle = "Crazy Gadget - Gold Beetle"
crazy_gadget_upgrade = "Crazy Gadget - Upgrade"
final_rush_1 = "Final Rush - 1"
@ -84,6 +120,9 @@ 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_omo_1 = "Final Rush - Omochao 1"
final_rush_omo_2 = "Final Rush - Omochao 2"
final_rush_omo_3 = "Final Rush - Omochao 3"
final_rush_beetle = "Final Rush - Gold Beetle"
final_rush_upgrade = "Final Rush - Upgrade"
@ -102,6 +141,16 @@ prison_lane_pipe_3 = "Prison Lane - Pipe 3"
prison_lane_hidden_1 = "Prison Lane - Hidden 1"
prison_lane_hidden_2 = "Prison Lane - Hidden 2"
prison_lane_hidden_3 = "Prison Lane - Hidden 3"
prison_lane_omo_1 = "Prison Lane - Omochao 1"
prison_lane_omo_2 = "Prison Lane - Omochao 2"
prison_lane_omo_3 = "Prison Lane - Omochao 3"
prison_lane_omo_4 = "Prison Lane - Omochao 4"
prison_lane_omo_5 = "Prison Lane - Omochao 5"
prison_lane_omo_6 = "Prison Lane - Omochao 6"
prison_lane_omo_7 = "Prison Lane - Omochao 7"
prison_lane_omo_8 = "Prison Lane - Omochao 8"
prison_lane_omo_9 = "Prison Lane - Omochao 9"
prison_lane_omo_10 = "Prison Lane - Omochao 10"
prison_lane_beetle = "Prison Lane - Gold Beetle"
prison_lane_upgrade = "Prison Lane - Upgrade"
mission_street_1 = "Mission Street - 1"
@ -119,6 +168,14 @@ mission_street_hidden_1 = "Mission Street - Hidden 1"
mission_street_hidden_2 = "Mission Street - Hidden 2"
mission_street_hidden_3 = "Mission Street - Hidden 3"
mission_street_hidden_4 = "Mission Street - Hidden 4"
mission_street_omo_1 = "Mission Street - Omochao 1"
mission_street_omo_2 = "Mission Street - Omochao 2"
mission_street_omo_3 = "Mission Street - Omochao 3"
mission_street_omo_4 = "Mission Street - Omochao 4"
mission_street_omo_5 = "Mission Street - Omochao 5"
mission_street_omo_6 = "Mission Street - Omochao 6"
mission_street_omo_7 = "Mission Street - Omochao 7"
mission_street_omo_8 = "Mission Street - Omochao 8"
mission_street_beetle = "Mission Street - Gold Beetle"
mission_street_upgrade = "Mission Street - Upgrade"
route_101_1 = "Route 101 - 1"
@ -138,6 +195,10 @@ 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_omo_1 = "Hidden Base - Omochao 1"
hidden_base_omo_2 = "Hidden Base - Omochao 2"
hidden_base_omo_3 = "Hidden Base - Omochao 3"
hidden_base_omo_4 = "Hidden Base - Omochao 4"
hidden_base_beetle = "Hidden Base - Gold Beetle"
hidden_base_upgrade = "Hidden Base - Upgrade"
eternal_engine_1 = "Eternal Engine - 1"
@ -153,6 +214,18 @@ 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_omo_1 = "Eternal Engine - Omochao 1"
eternal_engine_omo_2 = "Eternal Engine - Omochao 2"
eternal_engine_omo_3 = "Eternal Engine - Omochao 3"
eternal_engine_omo_4 = "Eternal Engine - Omochao 4"
eternal_engine_omo_5 = "Eternal Engine - Omochao 5"
eternal_engine_omo_6 = "Eternal Engine - Omochao 6"
eternal_engine_omo_7 = "Eternal Engine - Omochao 7"
eternal_engine_omo_8 = "Eternal Engine - Omochao 8"
eternal_engine_omo_9 = "Eternal Engine - Omochao 9"
eternal_engine_omo_10 = "Eternal Engine - Omochao 10"
eternal_engine_omo_11 = "Eternal Engine - Omochao 11"
eternal_engine_omo_12 = "Eternal Engine - Omochao 12"
eternal_engine_beetle = "Eternal Engine - Gold Beetle"
eternal_engine_upgrade = "Eternal Engine - Upgrade"
@ -168,6 +241,16 @@ wild_canyon_chao_3 = "Wild Canyon - Chao Key 3"
wild_canyon_pipe_1 = "Wild Canyon - Pipe 1"
wild_canyon_pipe_2 = "Wild Canyon - Pipe 2"
wild_canyon_pipe_3 = "Wild Canyon - Pipe 3"
wild_canyon_omo_1 = "Wild Canyon - Omochao 1"
wild_canyon_omo_2 = "Wild Canyon - Omochao 2"
wild_canyon_omo_3 = "Wild Canyon - Omochao 3"
wild_canyon_omo_4 = "Wild Canyon - Omochao 4"
wild_canyon_omo_5 = "Wild Canyon - Omochao 5"
wild_canyon_omo_6 = "Wild Canyon - Omochao 6"
wild_canyon_omo_7 = "Wild Canyon - Omochao 7"
wild_canyon_omo_8 = "Wild Canyon - Omochao 8"
wild_canyon_omo_9 = "Wild Canyon - Omochao 9"
wild_canyon_omo_10 = "Wild Canyon - Omochao 10"
wild_canyon_beetle = "Wild Canyon - Gold Beetle"
wild_canyon_upgrade = "Wild Canyon - Upgrade"
pumpkin_hill_1 = "Pumpkin Hill - 1"
@ -180,6 +263,17 @@ pumpkin_hill_chao_2 = "Pumpkin Hill - Chao Key 2"
pumpkin_hill_chao_3 = "Pumpkin Hill - Chao Key 3"
pumpkin_hill_pipe_1 = "Pumpkin Hill - Pipe 1"
pumpkin_hill_hidden_1 = "Pumpkin Hill - Hidden 1"
pumpkin_hill_omo_1 = "Pumpkin Hill - Omochao 1"
pumpkin_hill_omo_2 = "Pumpkin Hill - Omochao 2"
pumpkin_hill_omo_3 = "Pumpkin Hill - Omochao 3"
pumpkin_hill_omo_4 = "Pumpkin Hill - Omochao 4"
pumpkin_hill_omo_5 = "Pumpkin Hill - Omochao 5"
pumpkin_hill_omo_6 = "Pumpkin Hill - Omochao 6"
pumpkin_hill_omo_7 = "Pumpkin Hill - Omochao 7"
pumpkin_hill_omo_8 = "Pumpkin Hill - Omochao 8"
pumpkin_hill_omo_9 = "Pumpkin Hill - Omochao 9"
pumpkin_hill_omo_10 = "Pumpkin Hill - Omochao 10"
pumpkin_hill_omo_11 = "Pumpkin Hill - Omochao 11"
pumpkin_hill_upgrade = "Pumpkin Hill - Upgrade"
aquatic_mine_1 = "Aquatic Mine - 1"
aquatic_mine_2 = "Aquatic Mine - 2"
@ -192,6 +286,13 @@ 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_omo_1 = "Aquatic Mine - Omochao 1"
aquatic_mine_omo_2 = "Aquatic Mine - Omochao 2"
aquatic_mine_omo_3 = "Aquatic Mine - Omochao 3"
aquatic_mine_omo_4 = "Aquatic Mine - Omochao 4"
aquatic_mine_omo_5 = "Aquatic Mine - Omochao 5"
aquatic_mine_omo_6 = "Aquatic Mine - Omochao 6"
aquatic_mine_omo_7 = "Aquatic Mine - Omochao 7"
aquatic_mine_beetle = "Aquatic Mine - Gold Beetle"
aquatic_mine_upgrade = "Aquatic Mine - Upgrade"
death_chamber_1 = "Death Chamber - 1"
@ -207,6 +308,15 @@ 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_omo_1 = "Death Chamber - Omochao 1"
death_chamber_omo_2 = "Death Chamber - Omochao 2"
death_chamber_omo_3 = "Death Chamber - Omochao 3"
death_chamber_omo_4 = "Death Chamber - Omochao 4"
death_chamber_omo_5 = "Death Chamber - Omochao 5"
death_chamber_omo_6 = "Death Chamber - Omochao 6"
death_chamber_omo_7 = "Death Chamber - Omochao 7"
death_chamber_omo_8 = "Death Chamber - Omochao 8"
death_chamber_omo_9 = "Death Chamber - Omochao 9"
death_chamber_beetle = "Death Chamber - Gold Beetle"
death_chamber_upgrade = "Death Chamber - Upgrade"
meteor_herd_1 = "Meteor Herd - 1"
@ -220,6 +330,9 @@ 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_omo_1 = "Meteor Herd - Omochao 1"
meteor_herd_omo_2 = "Meteor Herd - Omochao 2"
meteor_herd_omo_3 = "Meteor Herd - Omochao 3"
meteor_herd_beetle = "Meteor Herd - Gold Beetle"
meteor_herd_upgrade = "Meteor Herd - Upgrade"
@ -239,6 +352,14 @@ radical_highway_pipe_3 = "Radical Highway - Pipe 3"
radical_highway_hidden_1 = "Radical Highway - Hidden 1"
radical_highway_hidden_2 = "Radical Highway - Hidden 2"
radical_highway_hidden_3 = "Radical Highway - Hidden 3"
radical_highway_omo_1 = "Radical Highway - Omochao 1"
radical_highway_omo_2 = "Radical Highway - Omochao 2"
radical_highway_omo_3 = "Radical Highway - Omochao 3"
radical_highway_omo_4 = "Radical Highway - Omochao 4"
radical_highway_omo_5 = "Radical Highway - Omochao 5"
radical_highway_omo_6 = "Radical Highway - Omochao 6"
radical_highway_omo_7 = "Radical Highway - Omochao 7"
radical_highway_omo_8 = "Radical Highway - Omochao 8"
radical_highway_beetle = "Radical Highway - Gold Beetle"
radical_highway_upgrade = "Radical Highway - Upgrade"
white_jungle_1 = "White Jungle - 1"
@ -256,6 +377,11 @@ 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_omo_1 = "White Jungle - Omochao 1"
white_jungle_omo_2 = "White Jungle - Omochao 2"
white_jungle_omo_3 = "White Jungle - Omochao 3"
white_jungle_omo_4 = "White Jungle - Omochao 4"
white_jungle_omo_5 = "White Jungle - Omochao 5"
white_jungle_beetle = "White Jungle - Gold Beetle"
white_jungle_upgrade = "White Jungle - Upgrade"
sky_rail_1 = "Sky Rail - 1"
@ -285,6 +411,7 @@ 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_omo_1 = "Final Chase - Omochao 1"
final_chase_beetle = "Final Chase - Gold Beetle"
final_chase_upgrade = "Final Chase - Upgrade"
@ -302,6 +429,12 @@ iron_gate_pipe_2 = "Iron Gate - Pipe 2"
iron_gate_pipe_3 = "Iron Gate - Pipe 3"
iron_gate_pipe_4 = "Iron Gate - Pipe 4"
iron_gate_pipe_5 = "Iron Gate - Pipe 5"
iron_gate_omo_1 = "Iron Gate - Omochao 1"
iron_gate_omo_2 = "Iron Gate - Omochao 2"
iron_gate_omo_3 = "Iron Gate - Omochao 3"
iron_gate_omo_4 = "Iron Gate - Omochao 4"
iron_gate_omo_5 = "Iron Gate - Omochao 5"
iron_gate_omo_6 = "Iron Gate - Omochao 6"
iron_gate_beetle = "Iron Gate - Gold Beetle"
iron_gate_upgrade = "Iron Gate - Upgrade"
sand_ocean_1 = "Sand Ocean - 1"
@ -317,6 +450,8 @@ sand_ocean_pipe_2 = "Sand Ocean - Pipe 2"
sand_ocean_pipe_3 = "Sand Ocean - Pipe 3"
sand_ocean_pipe_4 = "Sand Ocean - Pipe 4"
sand_ocean_pipe_5 = "Sand Ocean - Pipe 5"
sand_ocean_omo_1 = "Sand Ocean - Omochao 1"
sand_ocean_omo_2 = "Sand Ocean - Omochao 2"
sand_ocean_beetle = "Sand Ocean - Gold Beetle"
sand_ocean_upgrade = "Sand Ocean - Upgrade"
lost_colony_1 = "Lost Colony - 1"
@ -330,6 +465,14 @@ 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_omo_1 = "Lost Colony - Omochao 1"
lost_colony_omo_2 = "Lost Colony - Omochao 2"
lost_colony_omo_3 = "Lost Colony - Omochao 3"
lost_colony_omo_4 = "Lost Colony - Omochao 4"
lost_colony_omo_5 = "Lost Colony - Omochao 5"
lost_colony_omo_6 = "Lost Colony - Omochao 6"
lost_colony_omo_7 = "Lost Colony - Omochao 7"
lost_colony_omo_8 = "Lost Colony - Omochao 8"
lost_colony_beetle = "Lost Colony - Gold Beetle"
lost_colony_upgrade = "Lost Colony - Upgrade"
weapons_bed_1 = "Weapons Bed - 1"
@ -345,6 +488,9 @@ 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_omo_1 = "Weapons Bed - Omochao 1"
weapons_bed_omo_2 = "Weapons Bed - Omochao 2"
weapons_bed_omo_3 = "Weapons Bed - Omochao 3"
weapons_bed_upgrade = "Weapons Bed - Upgrade"
cosmic_wall_1 = "Cosmic Wall - 1"
cosmic_wall_2 = "Cosmic Wall - 2"
@ -359,6 +505,7 @@ 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_omo_1 = "Cosmic Wall - Omochao 1"
cosmic_wall_beetle = "Cosmic Wall - Gold Beetle"
cosmic_wall_upgrade = "Cosmic Wall - Upgrade"
@ -373,6 +520,18 @@ dry_lagoon_chao_2 = "Dry Lagoon - Chao Key 2"
dry_lagoon_chao_3 = "Dry Lagoon - Chao Key 3"
dry_lagoon_pipe_1 = "Dry Lagoon - Pipe 1"
dry_lagoon_hidden_1 = "Dry Lagoon - Hidden 1"
dry_lagoon_omo_1 = "Dry Lagoon - Omochao 1"
dry_lagoon_omo_2 = "Dry Lagoon - Omochao 2"
dry_lagoon_omo_3 = "Dry Lagoon - Omochao 3"
dry_lagoon_omo_4 = "Dry Lagoon - Omochao 4"
dry_lagoon_omo_5 = "Dry Lagoon - Omochao 5"
dry_lagoon_omo_6 = "Dry Lagoon - Omochao 6"
dry_lagoon_omo_7 = "Dry Lagoon - Omochao 7"
dry_lagoon_omo_8 = "Dry Lagoon - Omochao 8"
dry_lagoon_omo_9 = "Dry Lagoon - Omochao 9"
dry_lagoon_omo_10 = "Dry Lagoon - Omochao 10"
dry_lagoon_omo_11 = "Dry Lagoon - Omochao 11"
dry_lagoon_omo_12 = "Dry Lagoon - Omochao 12"
dry_lagoon_beetle = "Dry Lagoon - Gold Beetle"
dry_lagoon_upgrade = "Dry Lagoon - Upgrade"
egg_quarters_1 = "Egg Quarters - 1"
@ -387,6 +546,13 @@ egg_quarters_pipe_1 = "Egg Quarters - Pipe 1"
egg_quarters_pipe_2 = "Egg Quarters - Pipe 2"
egg_quarters_hidden_1 = "Egg Quarters - Hidden 1"
egg_quarters_hidden_2 = "Egg Quarters - Hidden 2"
egg_quarters_omo_1 = "Egg Quarters - Omochao 1"
egg_quarters_omo_2 = "Egg Quarters - Omochao 2"
egg_quarters_omo_3 = "Egg Quarters - Omochao 3"
egg_quarters_omo_4 = "Egg Quarters - Omochao 4"
egg_quarters_omo_5 = "Egg Quarters - Omochao 5"
egg_quarters_omo_6 = "Egg Quarters - Omochao 6"
egg_quarters_omo_7 = "Egg Quarters - Omochao 7"
egg_quarters_beetle = "Egg Quarters - Gold Beetle"
egg_quarters_upgrade = "Egg Quarters - Upgrade"
security_hall_1 = "Security Hall - 1"
@ -399,6 +565,18 @@ 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_omo_1 = "Security Hall - Omochao 1"
security_hall_omo_2 = "Security Hall - Omochao 2"
security_hall_omo_3 = "Security Hall - Omochao 3"
security_hall_omo_4 = "Security Hall - Omochao 4"
security_hall_omo_5 = "Security Hall - Omochao 5"
security_hall_omo_6 = "Security Hall - Omochao 6"
security_hall_omo_7 = "Security Hall - Omochao 7"
security_hall_omo_8 = "Security Hall - Omochao 8"
security_hall_omo_9 = "Security Hall - Omochao 9"
security_hall_omo_10 = "Security Hall - Omochao 10"
security_hall_omo_11 = "Security Hall - Omochao 11"
security_hall_omo_12 = "Security Hall - Omochao 12"
security_hall_beetle = "Security Hall - Gold Beetle"
security_hall_upgrade = "Security Hall - Upgrade"
route_280_1 = "Route 280 - 1"
@ -418,6 +596,11 @@ 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_omo_1 = "Mad Space - Omochao 1"
mad_space_omo_2 = "Mad Space - Omochao 2"
mad_space_omo_3 = "Mad Space - Omochao 3"
mad_space_omo_4 = "Mad Space - Omochao 4"
mad_space_omo_5 = "Mad Space - Omochao 5"
mad_space_beetle = "Mad Space - Gold Beetle"
mad_space_upgrade = "Mad Space - Upgrade"
@ -435,6 +618,15 @@ 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_omo_1 = "Cannon Core - Omochao 1"
cannon_core_omo_2 = "Cannon Core - Omochao 2"
cannon_core_omo_3 = "Cannon Core - Omochao 3"
cannon_core_omo_4 = "Cannon Core - Omochao 4"
cannon_core_omo_5 = "Cannon Core - Omochao 5"
cannon_core_omo_6 = "Cannon Core - Omochao 6"
cannon_core_omo_7 = "Cannon Core - Omochao 7"
cannon_core_omo_8 = "Cannon Core - Omochao 8"
cannon_core_omo_9 = "Cannon Core - Omochao 9"
cannon_core_hidden_1 = "Cannon Core - Hidden 1"
cannon_core_beetle = "Cannon Core - Gold Beetle"
@ -518,6 +710,30 @@ chao_standard_karate = "Chao Karate - Standard"
chao_expert_karate = "Chao Karate - Expert"
chao_super_karate = "Chao Karate - Super"
# Kart Race Definitions
kart_race_beginner_sonic = "Kart Race - Beginner - Sonic"
kart_race_beginner_tails = "Kart Race - Beginner - Tails"
kart_race_beginner_knuckles = "Kart Race - Beginner - Knuckles"
kart_race_beginner_shadow = "Kart Race - Beginner - Shadow"
kart_race_beginner_eggman = "Kart Race - Beginner - Eggman"
kart_race_beginner_rouge = "Kart Race - Beginner - Rouge"
kart_race_standard_sonic = "Kart Race - Standard - Sonic"
kart_race_standard_tails = "Kart Race - Standard - Tails"
kart_race_standard_knuckles = "Kart Race - Standard - Knuckles"
kart_race_standard_shadow = "Kart Race - Standard - Shadow"
kart_race_standard_eggman = "Kart Race - Standard - Eggman"
kart_race_standard_rouge = "Kart Race - Standard - Rouge"
kart_race_expert_sonic = "Kart Race - Expert - Sonic"
kart_race_expert_tails = "Kart Race - Expert - Tails"
kart_race_expert_knuckles = "Kart Race - Expert - Knuckles"
kart_race_expert_shadow = "Kart Race - Expert - Shadow"
kart_race_expert_eggman = "Kart Race - Expert - Eggman"
kart_race_expert_rouge = "Kart Race - Expert - Rouge"
kart_race_beginner = "Kart Race - Beginner"
kart_race_standard = "Kart Race - Standard"
kart_race_expert = "Kart Race - Expert"
# Other Definitions
green_hill = "Green Hill"
green_hill_chao_1 = "Green Hill - Chao Key 1"
@ -582,6 +798,13 @@ biolizard_region = "Biolizard"
green_hill_region = "Green Hill"
grand_prix = "Grand Prix"
grand_prix_region = "Grand Prix"
chao_garden_beginner_region = "Chao Garden - Beginner"
chao_garden_intermediate_region = "Chao Garden - Intermediate"
chao_garden_expert_region = "Chao Garden - Expert"
kart_race_beginner_region = "Kart Race - Beginner"
kart_race_standard_region = "Kart Race - Intermediate"
kart_race_expert_region = "Kart Race - Expert"

View File

@ -9,11 +9,13 @@ class Goal(Choice):
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
Grand Prix: Win every race in Kart Race Mode (all standard levels are disabled)
"""
display_name = "Goal"
option_biolizard = 0
option_chaos_emerald_hunt = 1
option_finalhazard_chaos_emerald_hunt = 2
option_grand_prix = 3
default = 0
@ -84,6 +86,24 @@ class DarknessTrapWeight(BaseTrapWeight):
display_name = "Darkness Trap Weight"
class PongTrapWeight(BaseTrapWeight):
"""
Likelihood of receiving a trap which forces you to play a Pong minigame
"""
display_name = "Pong Trap Weight"
class MinigameTrapDifficulty(Choice):
"""
How difficult any Minigame-style traps are
"""
display_name = "Minigame Trap Difficulty"
option_easy = 0
option_medium = 1
option_hard = 2
default = 1
class JunkFillPercentage(Range):
"""
Replace a percentage of non-required emblems in the item pool with random junk items
@ -150,6 +170,27 @@ class Beetlesanity(Toggle):
display_name = "Beetlesanity"
class Omosanity(Toggle):
"""
Determines whether activating Omochao grants checks
"""
display_name = "Omosanity"
class KartRaceChecks(Choice):
"""
Determines whether Kart Race Mode grants checks
None: No Kart Races grant checks
Mini: Each Kart Race difficulty must be beaten only once
Full: Every Character must separately beat each Kart Race difficulty
"""
display_name = "Kart Race Checks"
option_none = 0
option_mini = 1
option_full = 2
default = 0
class EmblemPercentageForCannonsCore(Range):
"""
Allows logic to gate the final mission behind a number of Emblems
@ -440,6 +481,27 @@ class CannonsCoreMission5(DefaultOnToggle):
display_name = "Cannon's Core Mission 5"
class RingLoss(Choice):
"""
How taking damage is handled
Classic: You lose all of your rings when hit
Modern: You lose 20 rings when hit
OHKO: You die immediately when hit (NOTE: Some Hard Logic tricks require damage boosts!)
"""
display_name = "SADX Music"
option_classic = 0
option_modern = 1
option_ohko = 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 SADXMusic(Choice):
"""
Whether the randomizer will include Sonic Adventure DX Music in the music pool
@ -515,6 +577,8 @@ sa2b_options: typing.Dict[str, type(Option)] = {
"keysanity": Keysanity,
"whistlesanity": Whistlesanity,
"beetlesanity": Beetlesanity,
"omosanity": Omosanity,
"kart_race_checks": KartRaceChecks,
"required_rank": RequiredRank,
"emblem_percentage_for_cannons_core": EmblemPercentageForCannonsCore,
"required_cannons_core_missions": RequiredCannonsCoreMissions,
@ -533,6 +597,9 @@ sa2b_options: typing.Dict[str, type(Option)] = {
"gravity_trap_weight": GravityTrapWeight,
"exposition_trap_weight": ExpositionTrapWeight,
#"darkness_trap_weight": DarknessTrapWeight,
"pong_trap_weight": PongTrapWeight,
"minigame_trap_difficulty": MinigameTrapDifficulty,
"ring_loss": RingLoss,
"sadx_music": SADXMusic,
"music_shuffle": MusicShuffle,
"narrator": Narrator,

View File

@ -134,6 +134,20 @@ def create_regions(world, player: int, active_locations):
LocationName.city_escape_hidden_3,
LocationName.city_escape_hidden_4,
LocationName.city_escape_hidden_5,
LocationName.city_escape_omo_1,
LocationName.city_escape_omo_2,
LocationName.city_escape_omo_3,
LocationName.city_escape_omo_4,
LocationName.city_escape_omo_5,
LocationName.city_escape_omo_6,
LocationName.city_escape_omo_7,
LocationName.city_escape_omo_8,
LocationName.city_escape_omo_9,
LocationName.city_escape_omo_10,
LocationName.city_escape_omo_11,
LocationName.city_escape_omo_12,
LocationName.city_escape_omo_13,
LocationName.city_escape_omo_14,
LocationName.city_escape_beetle,
LocationName.city_escape_upgrade,
]
@ -150,6 +164,11 @@ def create_regions(world, player: int, active_locations):
LocationName.metal_harbor_chao_2,
LocationName.metal_harbor_chao_3,
LocationName.metal_harbor_pipe_1,
LocationName.metal_harbor_omo_1,
LocationName.metal_harbor_omo_2,
LocationName.metal_harbor_omo_3,
LocationName.metal_harbor_omo_4,
LocationName.metal_harbor_omo_5,
LocationName.metal_harbor_beetle,
LocationName.metal_harbor_upgrade,
]
@ -190,6 +209,10 @@ def create_regions(world, player: int, active_locations):
LocationName.pyramid_cave_pipe_2,
LocationName.pyramid_cave_pipe_3,
LocationName.pyramid_cave_pipe_4,
LocationName.pyramid_cave_omo_1,
LocationName.pyramid_cave_omo_2,
LocationName.pyramid_cave_omo_3,
LocationName.pyramid_cave_omo_4,
LocationName.pyramid_cave_beetle,
LocationName.pyramid_cave_upgrade,
]
@ -210,6 +233,19 @@ def create_regions(world, player: int, active_locations):
LocationName.crazy_gadget_pipe_3,
LocationName.crazy_gadget_pipe_4,
LocationName.crazy_gadget_hidden_1,
LocationName.crazy_gadget_omo_1,
LocationName.crazy_gadget_omo_2,
LocationName.crazy_gadget_omo_3,
LocationName.crazy_gadget_omo_4,
LocationName.crazy_gadget_omo_5,
LocationName.crazy_gadget_omo_6,
LocationName.crazy_gadget_omo_7,
LocationName.crazy_gadget_omo_8,
LocationName.crazy_gadget_omo_9,
LocationName.crazy_gadget_omo_10,
LocationName.crazy_gadget_omo_11,
LocationName.crazy_gadget_omo_12,
LocationName.crazy_gadget_omo_13,
LocationName.crazy_gadget_beetle,
LocationName.crazy_gadget_upgrade,
]
@ -227,6 +263,9 @@ def create_regions(world, player: int, active_locations):
LocationName.final_rush_chao_3,
LocationName.final_rush_pipe_1,
LocationName.final_rush_pipe_2,
LocationName.final_rush_omo_1,
LocationName.final_rush_omo_2,
LocationName.final_rush_omo_3,
LocationName.final_rush_beetle,
LocationName.final_rush_upgrade,
]
@ -248,6 +287,16 @@ def create_regions(world, player: int, active_locations):
LocationName.prison_lane_hidden_1,
LocationName.prison_lane_hidden_2,
LocationName.prison_lane_hidden_3,
LocationName.prison_lane_omo_1,
LocationName.prison_lane_omo_2,
LocationName.prison_lane_omo_3,
LocationName.prison_lane_omo_4,
LocationName.prison_lane_omo_5,
LocationName.prison_lane_omo_6,
LocationName.prison_lane_omo_7,
LocationName.prison_lane_omo_8,
LocationName.prison_lane_omo_9,
LocationName.prison_lane_omo_10,
LocationName.prison_lane_beetle,
LocationName.prison_lane_upgrade,
]
@ -270,6 +319,14 @@ def create_regions(world, player: int, active_locations):
LocationName.mission_street_hidden_2,
LocationName.mission_street_hidden_3,
LocationName.mission_street_hidden_4,
LocationName.mission_street_omo_1,
LocationName.mission_street_omo_2,
LocationName.mission_street_omo_3,
LocationName.mission_street_omo_4,
LocationName.mission_street_omo_5,
LocationName.mission_street_omo_6,
LocationName.mission_street_omo_7,
LocationName.mission_street_omo_8,
LocationName.mission_street_beetle,
LocationName.mission_street_upgrade,
]
@ -299,6 +356,10 @@ def create_regions(world, player: int, active_locations):
LocationName.hidden_base_pipe_3,
LocationName.hidden_base_pipe_4,
LocationName.hidden_base_pipe_5,
LocationName.hidden_base_omo_1,
LocationName.hidden_base_omo_2,
LocationName.hidden_base_omo_3,
LocationName.hidden_base_omo_4,
LocationName.hidden_base_beetle,
LocationName.hidden_base_upgrade,
]
@ -319,6 +380,18 @@ def create_regions(world, player: int, active_locations):
LocationName.eternal_engine_pipe_3,
LocationName.eternal_engine_pipe_4,
LocationName.eternal_engine_pipe_5,
LocationName.eternal_engine_omo_1,
LocationName.eternal_engine_omo_2,
LocationName.eternal_engine_omo_3,
LocationName.eternal_engine_omo_4,
LocationName.eternal_engine_omo_5,
LocationName.eternal_engine_omo_6,
LocationName.eternal_engine_omo_7,
LocationName.eternal_engine_omo_8,
LocationName.eternal_engine_omo_9,
LocationName.eternal_engine_omo_10,
LocationName.eternal_engine_omo_11,
LocationName.eternal_engine_omo_12,
LocationName.eternal_engine_beetle,
LocationName.eternal_engine_upgrade,
]
@ -337,6 +410,16 @@ def create_regions(world, player: int, active_locations):
LocationName.wild_canyon_pipe_1,
LocationName.wild_canyon_pipe_2,
LocationName.wild_canyon_pipe_3,
LocationName.wild_canyon_omo_1,
LocationName.wild_canyon_omo_2,
LocationName.wild_canyon_omo_3,
LocationName.wild_canyon_omo_4,
LocationName.wild_canyon_omo_5,
LocationName.wild_canyon_omo_6,
LocationName.wild_canyon_omo_7,
LocationName.wild_canyon_omo_8,
LocationName.wild_canyon_omo_9,
LocationName.wild_canyon_omo_10,
LocationName.wild_canyon_beetle,
LocationName.wild_canyon_upgrade,
]
@ -354,6 +437,17 @@ def create_regions(world, player: int, active_locations):
LocationName.pumpkin_hill_chao_3,
LocationName.pumpkin_hill_pipe_1,
LocationName.pumpkin_hill_hidden_1,
LocationName.pumpkin_hill_omo_1,
LocationName.pumpkin_hill_omo_2,
LocationName.pumpkin_hill_omo_3,
LocationName.pumpkin_hill_omo_4,
LocationName.pumpkin_hill_omo_5,
LocationName.pumpkin_hill_omo_6,
LocationName.pumpkin_hill_omo_7,
LocationName.pumpkin_hill_omo_8,
LocationName.pumpkin_hill_omo_9,
LocationName.pumpkin_hill_omo_10,
LocationName.pumpkin_hill_omo_11,
LocationName.pumpkin_hill_upgrade,
]
pumpkin_hill_region = create_region(world, player, active_locations, LocationName.pumpkin_hill_region,
@ -371,6 +465,13 @@ def create_regions(world, player: int, active_locations):
LocationName.aquatic_mine_pipe_1,
LocationName.aquatic_mine_pipe_2,
LocationName.aquatic_mine_pipe_3,
LocationName.aquatic_mine_omo_1,
LocationName.aquatic_mine_omo_2,
LocationName.aquatic_mine_omo_3,
LocationName.aquatic_mine_omo_4,
LocationName.aquatic_mine_omo_5,
LocationName.aquatic_mine_omo_6,
LocationName.aquatic_mine_omo_7,
LocationName.aquatic_mine_beetle,
LocationName.aquatic_mine_upgrade,
]
@ -391,6 +492,15 @@ def create_regions(world, player: int, active_locations):
LocationName.death_chamber_pipe_3,
LocationName.death_chamber_hidden_1,
LocationName.death_chamber_hidden_2,
LocationName.death_chamber_omo_1,
LocationName.death_chamber_omo_2,
LocationName.death_chamber_omo_3,
LocationName.death_chamber_omo_4,
LocationName.death_chamber_omo_5,
LocationName.death_chamber_omo_6,
LocationName.death_chamber_omo_7,
LocationName.death_chamber_omo_8,
LocationName.death_chamber_omo_9,
LocationName.death_chamber_beetle,
LocationName.death_chamber_upgrade,
]
@ -409,6 +519,9 @@ def create_regions(world, player: int, active_locations):
LocationName.meteor_herd_pipe_1,
LocationName.meteor_herd_pipe_2,
LocationName.meteor_herd_pipe_3,
LocationName.meteor_herd_omo_1,
LocationName.meteor_herd_omo_2,
LocationName.meteor_herd_omo_3,
LocationName.meteor_herd_beetle,
LocationName.meteor_herd_upgrade,
]
@ -430,6 +543,14 @@ def create_regions(world, player: int, active_locations):
LocationName.radical_highway_hidden_1,
LocationName.radical_highway_hidden_2,
LocationName.radical_highway_hidden_3,
LocationName.radical_highway_omo_1,
LocationName.radical_highway_omo_2,
LocationName.radical_highway_omo_3,
LocationName.radical_highway_omo_4,
LocationName.radical_highway_omo_5,
LocationName.radical_highway_omo_6,
LocationName.radical_highway_omo_7,
LocationName.radical_highway_omo_8,
LocationName.radical_highway_beetle,
LocationName.radical_highway_upgrade,
]
@ -452,6 +573,11 @@ def create_regions(world, player: int, active_locations):
LocationName.white_jungle_hidden_1,
LocationName.white_jungle_hidden_2,
LocationName.white_jungle_hidden_3,
LocationName.white_jungle_omo_1,
LocationName.white_jungle_omo_2,
LocationName.white_jungle_omo_3,
LocationName.white_jungle_omo_4,
LocationName.white_jungle_omo_5,
LocationName.white_jungle_beetle,
LocationName.white_jungle_upgrade,
]
@ -491,6 +617,7 @@ def create_regions(world, player: int, active_locations):
LocationName.final_chase_pipe_1,
LocationName.final_chase_pipe_2,
LocationName.final_chase_pipe_3,
LocationName.final_chase_omo_1,
LocationName.final_chase_beetle,
LocationName.final_chase_upgrade,
]
@ -511,6 +638,12 @@ def create_regions(world, player: int, active_locations):
LocationName.iron_gate_pipe_3,
LocationName.iron_gate_pipe_4,
LocationName.iron_gate_pipe_5,
LocationName.iron_gate_omo_1,
LocationName.iron_gate_omo_2,
LocationName.iron_gate_omo_3,
LocationName.iron_gate_omo_4,
LocationName.iron_gate_omo_5,
LocationName.iron_gate_omo_6,
LocationName.iron_gate_beetle,
LocationName.iron_gate_upgrade,
]
@ -531,6 +664,8 @@ def create_regions(world, player: int, active_locations):
LocationName.sand_ocean_pipe_3,
LocationName.sand_ocean_pipe_4,
LocationName.sand_ocean_pipe_5,
LocationName.sand_ocean_omo_1,
LocationName.sand_ocean_omo_2,
LocationName.sand_ocean_beetle,
LocationName.sand_ocean_upgrade,
]
@ -549,6 +684,14 @@ def create_regions(world, player: int, active_locations):
LocationName.lost_colony_pipe_1,
LocationName.lost_colony_pipe_2,
LocationName.lost_colony_hidden_1,
LocationName.lost_colony_omo_1,
LocationName.lost_colony_omo_2,
LocationName.lost_colony_omo_3,
LocationName.lost_colony_omo_4,
LocationName.lost_colony_omo_5,
LocationName.lost_colony_omo_6,
LocationName.lost_colony_omo_7,
LocationName.lost_colony_omo_8,
LocationName.lost_colony_beetle,
LocationName.lost_colony_upgrade,
]
@ -569,6 +712,9 @@ def create_regions(world, player: int, active_locations):
LocationName.weapons_bed_pipe_3,
LocationName.weapons_bed_pipe_4,
LocationName.weapons_bed_pipe_5,
LocationName.weapons_bed_omo_1,
LocationName.weapons_bed_omo_2,
LocationName.weapons_bed_omo_3,
LocationName.weapons_bed_upgrade,
]
weapons_bed_region = create_region(world, player, active_locations, LocationName.weapons_bed_region,
@ -588,6 +734,7 @@ def create_regions(world, player: int, active_locations):
LocationName.cosmic_wall_pipe_3,
LocationName.cosmic_wall_pipe_4,
LocationName.cosmic_wall_pipe_5,
LocationName.cosmic_wall_omo_1,
LocationName.cosmic_wall_beetle,
LocationName.cosmic_wall_upgrade,
]
@ -605,6 +752,18 @@ def create_regions(world, player: int, active_locations):
LocationName.dry_lagoon_chao_3,
LocationName.dry_lagoon_pipe_1,
LocationName.dry_lagoon_hidden_1,
LocationName.dry_lagoon_omo_1,
LocationName.dry_lagoon_omo_2,
LocationName.dry_lagoon_omo_3,
LocationName.dry_lagoon_omo_4,
LocationName.dry_lagoon_omo_5,
LocationName.dry_lagoon_omo_6,
LocationName.dry_lagoon_omo_7,
LocationName.dry_lagoon_omo_8,
LocationName.dry_lagoon_omo_9,
LocationName.dry_lagoon_omo_10,
LocationName.dry_lagoon_omo_11,
LocationName.dry_lagoon_omo_12,
LocationName.dry_lagoon_beetle,
LocationName.dry_lagoon_upgrade,
]
@ -624,6 +783,13 @@ def create_regions(world, player: int, active_locations):
LocationName.egg_quarters_pipe_2,
LocationName.egg_quarters_hidden_1,
LocationName.egg_quarters_hidden_2,
LocationName.egg_quarters_omo_1,
LocationName.egg_quarters_omo_2,
LocationName.egg_quarters_omo_3,
LocationName.egg_quarters_omo_4,
LocationName.egg_quarters_omo_5,
LocationName.egg_quarters_omo_6,
LocationName.egg_quarters_omo_7,
LocationName.egg_quarters_beetle,
LocationName.egg_quarters_upgrade,
]
@ -641,6 +807,18 @@ def create_regions(world, player: int, active_locations):
LocationName.security_hall_chao_3,
LocationName.security_hall_pipe_1,
LocationName.security_hall_hidden_1,
LocationName.security_hall_omo_1,
LocationName.security_hall_omo_2,
LocationName.security_hall_omo_3,
LocationName.security_hall_omo_4,
LocationName.security_hall_omo_5,
LocationName.security_hall_omo_6,
LocationName.security_hall_omo_7,
LocationName.security_hall_omo_8,
LocationName.security_hall_omo_9,
LocationName.security_hall_omo_10,
LocationName.security_hall_omo_11,
LocationName.security_hall_omo_12,
LocationName.security_hall_beetle,
LocationName.security_hall_upgrade,
]
@ -670,6 +848,11 @@ def create_regions(world, player: int, active_locations):
LocationName.mad_space_pipe_2,
LocationName.mad_space_pipe_3,
LocationName.mad_space_pipe_4,
LocationName.mad_space_omo_1,
LocationName.mad_space_omo_2,
LocationName.mad_space_omo_3,
LocationName.mad_space_omo_4,
LocationName.mad_space_omo_5,
LocationName.mad_space_beetle,
LocationName.mad_space_upgrade,
]
@ -691,6 +874,15 @@ def create_regions(world, player: int, active_locations):
LocationName.cannon_core_pipe_4,
LocationName.cannon_core_pipe_5,
LocationName.cannon_core_hidden_1,
LocationName.cannon_core_omo_1,
LocationName.cannon_core_omo_2,
LocationName.cannon_core_omo_3,
LocationName.cannon_core_omo_4,
LocationName.cannon_core_omo_5,
LocationName.cannon_core_omo_6,
LocationName.cannon_core_omo_7,
LocationName.cannon_core_omo_8,
LocationName.cannon_core_omo_9,
LocationName.cannon_core_beetle,
]
cannon_core_region = create_region(world, player, active_locations, LocationName.cannon_core_region,
@ -782,6 +974,59 @@ def create_regions(world, player: int, active_locations):
chao_garden_expert_region = create_region(world, player, active_locations, LocationName.chao_garden_expert_region,
chao_garden_expert_region_locations)
kart_race_beginner_region_locations = []
if world.kart_race_checks[player] == 2:
kart_race_beginner_region_locations.extend([
LocationName.kart_race_beginner_sonic,
LocationName.kart_race_beginner_tails,
LocationName.kart_race_beginner_knuckles,
LocationName.kart_race_beginner_shadow,
LocationName.kart_race_beginner_eggman,
LocationName.kart_race_beginner_rouge,
])
if world.kart_race_checks[player] == 1:
kart_race_beginner_region_locations.append(LocationName.kart_race_beginner)
kart_race_beginner_region = create_region(world, player, active_locations, LocationName.kart_race_beginner_region,
kart_race_beginner_region_locations)
kart_race_standard_region_locations = []
if world.kart_race_checks[player] == 2:
kart_race_standard_region_locations.extend([
LocationName.kart_race_standard_sonic,
LocationName.kart_race_standard_tails,
LocationName.kart_race_standard_knuckles,
LocationName.kart_race_standard_shadow,
LocationName.kart_race_standard_eggman,
LocationName.kart_race_standard_rouge,
])
if world.kart_race_checks[player] == 1:
kart_race_standard_region_locations.append(LocationName.kart_race_standard)
kart_race_standard_region = create_region(world, player, active_locations, LocationName.kart_race_standard_region,
kart_race_standard_region_locations)
kart_race_expert_region_locations = []
if world.kart_race_checks[player] == 2:
kart_race_expert_region_locations.extend([
LocationName.kart_race_expert_sonic,
LocationName.kart_race_expert_tails,
LocationName.kart_race_expert_knuckles,
LocationName.kart_race_expert_shadow,
LocationName.kart_race_expert_eggman,
LocationName.kart_race_expert_rouge,
])
if world.kart_race_checks[player] == 1:
kart_race_expert_region_locations.append(LocationName.kart_race_expert)
kart_race_expert_region = create_region(world, player, active_locations, LocationName.kart_race_expert_region,
kart_race_expert_region_locations)
if world.goal[player] == 3:
grand_prix_region_locations = [
LocationName.grand_prix,
]
grand_prix_region = create_region(world, player, active_locations, LocationName.grand_prix_region,
grand_prix_region_locations)
world.regions += [grand_prix_region]
if world.goal[player] == 0 or world.goal[player] == 2:
biolizard_region_locations = [
LocationName.finalhazard,
@ -838,6 +1083,9 @@ def create_regions(world, player: int, active_locations):
chao_garden_beginner_region,
chao_garden_intermediate_region,
chao_garden_expert_region,
kart_race_beginner_region,
kart_race_standard_region,
kart_race_expert_region,
]
@ -867,6 +1115,8 @@ def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_em
state.has(ItemName.blue_emerald, player)))
if world.goal[player] == 2:
connect(world, player, names, LocationName.green_hill_region, LocationName.biolizard_region)
elif world.goal[player] == 3:
connect(world, player, names, LocationName.kart_race_expert_region, LocationName.grand_prix_region)
for i in range(len(gates[0].gate_levels)):
connect(world, player, names, LocationName.gate_0_region, shuffleable_regions[gates[0].gate_levels[i]])
@ -941,27 +1191,51 @@ def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_em
connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_beginner_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_intermediate_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_expert_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_standard_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_expert_region)
elif gates_len == 2:
connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_beginner_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_intermediate_region)
connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_expert_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_standard_region)
connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_expert_region)
elif gates_len == 3:
connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_beginner_region)
connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_intermediate_region)
connect(world, player, names, LocationName.gate_2_region, LocationName.chao_garden_expert_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region)
connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_standard_region)
connect(world, player, names, LocationName.gate_2_region, LocationName.kart_race_expert_region)
elif gates_len == 4:
connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_beginner_region)
connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_intermediate_region)
connect(world, player, names, LocationName.gate_3_region, LocationName.chao_garden_expert_region)
connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region)
connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_standard_region)
connect(world, player, names, LocationName.gate_3_region, LocationName.kart_race_expert_region)
elif gates_len == 5:
connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_beginner_region)
connect(world, player, names, LocationName.gate_2_region, LocationName.chao_garden_intermediate_region)
connect(world, player, names, LocationName.gate_3_region, LocationName.chao_garden_expert_region)
connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_beginner_region)
connect(world, player, names, LocationName.gate_2_region, LocationName.kart_race_standard_region)
connect(world, player, names, LocationName.gate_3_region, LocationName.kart_race_expert_region)
elif gates_len >= 6:
connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_beginner_region)
connect(world, player, names, LocationName.gate_2_region, LocationName.chao_garden_intermediate_region)
connect(world, player, names, LocationName.gate_4_region, LocationName.chao_garden_expert_region)
connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_beginner_region)
connect(world, player, names, LocationName.gate_2_region, LocationName.kart_race_standard_region)
connect(world, player, names, LocationName.gate_4_region, LocationName.kart_race_expert_region)
def create_region(world: MultiWorld, player: int, active_locations, name: str, locations=None):
ret = Region(name, player, world)

View File

@ -3,8 +3,8 @@ import typing
from BaseClasses import MultiWorld
from .Names import LocationName, ItemName
from .Locations import boss_gate_set
from ..AutoWorld import LogicMixin
from ..generic.Rules import add_rule, set_rule, CollectionRule
from worlds.AutoWorld import LogicMixin
from worlds.generic.Rules import add_rule, set_rule, CollectionRule
from .GateBosses import boss_has_requirement
from .Missions import stage_name_prefixes, mission_orders
@ -619,6 +619,174 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int):
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player))
# Omochao Upgrade Requirements
if world.omosanity[player]:
add_rule(world.get_location(LocationName.eternal_engine_omo_1, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_omo_2, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_omo_2, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.death_chamber_omo_2, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_2, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.radical_highway_omo_2, player),
lambda state: state.has(ItemName.shadow_air_shoes, player))
add_rule(world.get_location(LocationName.weapons_bed_omo_2, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.mission_street_omo_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_omo_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_omo_3, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.final_rush_omo_3, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.weapons_bed_omo_3, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.metal_harbor_omo_4, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_omo_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_omo_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_omo_4, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.death_chamber_omo_4, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.mad_space_omo_4, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cannon_core_omo_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.metal_harbor_omo_5, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_omo_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_5, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_5, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.white_jungle_omo_5, player),
lambda state: state.has(ItemName.shadow_air_shoes, player))
add_rule(world.get_location(LocationName.mad_space_omo_5, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cannon_core_omo_5, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.mission_street_omo_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_6, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_6, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_omo_6, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_omo_6, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.mission_street_omo_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_7, player),
lambda state: state.has(ItemName.knuckles_shovel_claws, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_7, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_omo_7, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_omo_7, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.knuckles_hammer_gloves, player) and
state.has(ItemName.knuckles_air_necklace, player))
add_rule(world.get_location(LocationName.mission_street_omo_8, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_8, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_8, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_8, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_omo_8, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.security_hall_omo_8, player),
lambda state: state.has(ItemName.rouge_mystic_melody, player) and
state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cannon_core_omo_8, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.knuckles_hammer_gloves, player) and
state.has(ItemName.knuckles_air_necklace, player))
add_rule(world.get_location(LocationName.death_chamber_omo_9, player),
lambda state: state.has(ItemName.knuckles_mystic_melody, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_9, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_9, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.cannon_core_omo_9, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.knuckles_hammer_gloves, player) and
state.has(ItemName.knuckles_air_necklace, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_10, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_10, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_11, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_11, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_12, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_12, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_bounce_bracelet, player) and
state.has(ItemName.sonic_flame_ring, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_13, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_bounce_bracelet, player) and
state.has(ItemName.sonic_flame_ring, player))
# Gold Beetle Upgrade Requirements
if world.beetlesanity[player]:
add_rule(world.get_location(LocationName.mission_street_beetle, player),
@ -715,9 +883,6 @@ def set_mission_upgrade_rules_hard(world: MultiWorld, player: int):
lambda state: state.has(ItemName.tails_booster, player))
# Mission 3 Upgrade Requirements
add_rule_safe(world, LocationName.city_escape_3, player,
lambda state: state.has(ItemName.sonic_bounce_bracelet, player) or
state.has(ItemName.sonic_mystic_melody, player))
add_rule_safe(world, LocationName.wild_canyon_3, player,
lambda state: state.has(ItemName.knuckles_shovel_claws, player))
add_rule_safe(world, LocationName.prison_lane_3, player,
@ -752,9 +917,7 @@ def set_mission_upgrade_rules_hard(world: MultiWorld, player: int):
add_rule_safe(world, LocationName.sand_ocean_3, player,
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule_safe(world, LocationName.egg_quarters_3, player,
lambda state: state.has(ItemName.rouge_mystic_melody, player) and
state.has(ItemName.rouge_pick_nails, player) and
state.has(ItemName.rouge_iron_boots, player))
lambda state: state.has(ItemName.rouge_mystic_melody, player))
add_rule_safe(world, LocationName.lost_colony_3, player,
lambda state: state.has(ItemName.eggman_mystic_melody, player) and
state.has(ItemName.eggman_jet_engine, player))
@ -845,8 +1008,6 @@ def set_mission_upgrade_rules_hard(world: MultiWorld, player: int):
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule_safe(world, LocationName.security_hall_5, player,
lambda state: state.has(ItemName.rouge_treasure_scope, player))
add_rule_safe(world, LocationName.mad_space_5, player,
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule_safe(world, LocationName.cosmic_wall_5, player,
lambda state: state.has(ItemName.eggman_jet_engine, player))
@ -968,8 +1129,6 @@ def set_mission_upgrade_rules_hard(world: MultiWorld, player: int):
add_rule(world.get_location(LocationName.cosmic_wall_pipe_1, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.mission_street_pipe_2, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_pipe_2, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_pipe_2, player),
@ -997,9 +1156,6 @@ def set_mission_upgrade_rules_hard(world: MultiWorld, player: int):
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_pipe_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_pipe_3, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player) or
state.has(ItemName.sonic_mystic_melody, player))
add_rule(world.get_location(LocationName.weapons_bed_pipe_3, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
@ -1056,6 +1212,125 @@ def set_mission_upgrade_rules_hard(world: MultiWorld, player: int):
add_rule(world.get_location(LocationName.cannon_core_hidden_1, player),
lambda state: state.has(ItemName.tails_booster, player))
# Omochao Upgrade Requirements
if world.omosanity[player]:
add_rule(world.get_location(LocationName.eternal_engine_omo_1, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_omo_2, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_2, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_2, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.weapons_bed_omo_2, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) or
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.hidden_base_omo_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.final_rush_omo_3, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.weapons_bed_omo_3, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.hidden_base_omo_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_4, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.cannon_core_omo_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.mission_street_omo_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_5, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.cannon_core_omo_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.mission_street_omo_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_6, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.lost_colony_omo_6, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_omo_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.mission_street_omo_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_7, player),
lambda state: state.has(ItemName.knuckles_shovel_claws, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.lost_colony_omo_7, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_omo_7, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.mission_street_omo_8, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_omo_8, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_8, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.lost_colony_omo_8, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.security_hall_omo_8, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cannon_core_omo_8, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.death_chamber_omo_9, player),
lambda state: state.has(ItemName.knuckles_mystic_melody, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_9, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.cannon_core_omo_9, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_10, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_11, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.eternal_engine_omo_12, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_12, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_flame_ring, player))
add_rule(world.get_location(LocationName.crazy_gadget_omo_13, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_flame_ring, player))
# Gold Beetle Upgrade Requirements
if world.beetlesanity[player]:
add_rule(world.get_location(LocationName.hidden_base_beetle, player),
@ -1096,11 +1371,12 @@ def set_rules(world: MultiWorld, player: int, gate_bosses: typing.Dict[int, int]
# Mission Progression Rules (Mission 1 begets Mission 2, etc.)
set_mission_progress_rules(world, player, mission_map, mission_count_map)
# Upgrade Requirements for each mission location
if world.logic_difficulty[player].value == 0:
set_mission_upgrade_rules_standard(world, player)
elif world.logic_difficulty[player].value == 1:
set_mission_upgrade_rules_hard(world, player)
if world.goal[player].value != 3:
# Upgrade Requirements for each mission location
if world.logic_difficulty[player].value == 0:
set_mission_upgrade_rules_standard(world, player)
elif world.logic_difficulty[player].value == 1:
set_mission_upgrade_rules_hard(world, player)
# Upgrade Requirements for each boss gate
set_boss_gate_rules(world, player, gate_bosses)

View File

@ -9,7 +9,7 @@ from .Regions import create_regions, shuffleable_regions, connect_regions, Level
gate_0_blacklist_regions
from .Rules import set_rules
from .Names import ItemName, LocationName
from ..AutoWorld import WebWorld, World
from worlds.AutoWorld import WebWorld, World
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
@ -52,7 +52,7 @@ class SA2BWorld(World):
game: str = "Sonic Adventure 2 Battle"
option_definitions = sa2b_options
topology_present = False
data_version = 4
data_version = 5
item_name_groups = item_groups
item_name_to_id = {name: data.code for name, data in item_table.items()}
@ -71,17 +71,21 @@ class SA2BWorld(World):
def _get_slot_data(self):
return {
"ModVersion": 200,
"ModVersion": 201,
"Goal": self.multiworld.goal[self.player].value,
"MusicMap": self.music_map,
"MissionMap": self.mission_map,
"MissionCountMap": self.mission_count_map,
"MusicShuffle": self.multiworld.music_shuffle[self.player].value,
"Narrator": self.multiworld.narrator[self.player].value,
"MinigameTrapDifficulty": self.multiworld.minigame_trap_difficulty[self.player].value,
"RingLoss": self.multiworld.ring_loss[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,
"OmochaoChecks": self.multiworld.omosanity[self.player].value,
"KartRaceChecks": self.multiworld.kart_race_checks[self.player].value,
"ChaoRaceChecks": self.multiworld.chao_race_checks[self.player].value,
"ChaoGardenDifficulty": self.multiworld.chao_garden_difficulty[self.player].value,
"DeathLink": self.multiworld.death_link[self.player].value,
@ -145,13 +149,45 @@ class SA2BWorld(World):
return levels_per_gate
def generate_early(self):
self.gate_bosses = get_gate_bosses(self.multiworld, self.player)
if self.multiworld.goal[self.player].value == 3:
# Turn off everything else for Grand Prix goal
self.multiworld.number_of_level_gates[self.player].value = 0
self.multiworld.emblem_percentage_for_cannons_core[self.player].value = 0
self.multiworld.junk_fill_percentage[self.player].value = 100
self.multiworld.trap_fill_percentage[self.player].value = 100
self.multiworld.omochao_trap_weight[self.player].value = 0
self.multiworld.timestop_trap_weight[self.player].value = 0
self.multiworld.confusion_trap_weight[self.player].value = 0
self.multiworld.tiny_trap_weight[self.player].value = 0
self.multiworld.gravity_trap_weight[self.player].value = 0
def generate_basic(self):
valid_trap_weights = self.multiworld.exposition_trap_weight[self.player].value + self.multiworld.pong_trap_weight[self.player].value
if valid_trap_weights == 0:
self.multiworld.exposition_trap_weight[self.player].value = 4
self.multiworld.pong_trap_weight[self.player].value = 4
if self.multiworld.kart_race_checks[self.player].value == 0:
self.multiworld.kart_race_checks[self.player].value = 2
self.gate_bosses = {}
else:
self.gate_bosses = get_gate_bosses(self.multiworld, self.player)
def create_regions(self):
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)
# Not Generate Basic
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))
elif self.multiworld.goal[self.player].value == 3:
self.multiworld.get_location(LocationName.grand_prix, self.player).place_locked_item(self.create_item(ItemName.maria))
itempool: typing.List[SA2BItem] = []
@ -159,18 +195,19 @@ class SA2BWorld(World):
total_required_locations = len(self.location_table)
total_required_locations -= 1; # Locked Victory Location
# Fill item pool with all required items
for item in {**upgrades_table}:
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}:
if self.multiworld.goal[self.player].value != 3:
# Fill item pool with all required items
for item in {**upgrades_table}:
itempool += self._create_items(item)
# Cap at 180 Emblems
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 250 Emblems
raw_emblem_count = total_required_locations - len(itempool)
total_emblem_count = min(raw_emblem_count, 180)
total_emblem_count = min(raw_emblem_count, 250)
extra_junk_count = raw_emblem_count - total_emblem_count
self.emblems_for_cannons_core = math.floor(
@ -234,6 +271,7 @@ class SA2BWorld(World):
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)
trap_weights += ([ItemName.pong_trap] * self.multiworld.pong_trap_weight[self.player].value)
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))
@ -309,13 +347,6 @@ class SA2BWorld(World):
self.music_map = dict(zip(musiclist_o, musiclist_s))
def create_regions(self):
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)
def create_item(self, name: str, force_non_progression=False) -> Item:
data = item_table[name]

View File

@ -10,11 +10,11 @@ The randomizer shuffles emblems and upgrade items into the AP item pool. The sto
## What is the goal of Sonic Adventure 2: Battle when randomized?
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.
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. If the Grand Prix goal is selected, the objective is to complete all levels in the kart race mode.
## What items and locations get shuffled?
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.
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, omochao, 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 250 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?