SA2B: v2.2 Content Update (#1904)

* Ice Trap Support

* Support Animalsanity

* Add option for controlling number of emblems in pool

* Support Slow Trap

* Support Cutscene Traps

* Support Voice Shuffle

* Handle Boss Rush goals

* Fix create item reference to self.multiworld

* Support Ringlink

* Reduce beep frequency to 20

* Add Boss Rush Chaos Emerald Hunt Goal

* Fix Eternal Engine - Pipe 1 logic

* Add Chao voice shuffle

* Remove unused option

* Adjust wording of Required Cannon's Core Missions

* Fix incorrect region assignment

* Fix incorrect animal logics

* Fix Chao Race tooltip

* Remove Green Hill Animal Location

* Add Location Count info to tooltips

* Don't allow M4 first if animalsanity is active

* Add Iron Boots to Standard Logic Egg Quarters 5

* Make Vanilla Boss Rush actually Vanilla

* Increment Mod Version

* Increment Data Package Version

---------

Co-authored-by: RaspberrySpaceJam <tyler.summers@gmail.com>
This commit is contained in:
PoryGone 2023-06-27 17:38:58 -04:00 committed by GitHub
parent d51e0ec0ab
commit 1ced726d31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 3067 additions and 585 deletions

View File

@ -29,6 +29,14 @@ gate_bosses_with_requirements_table = {
king_boom_boo: 10, king_boom_boo: 10,
} }
extra_boss_rush_bosses_table = {
speed_characters_1: 11,
speed_characters_2: 12,
mech_characters_1: 13,
mech_characters_2: 14,
hunt_characters_1: 15,
}
all_gate_bosses_table = { all_gate_bosses_table = {
**gate_bosses_no_requirements_table, **gate_bosses_no_requirements_table,
**gate_bosses_with_requirements_table, **gate_bosses_with_requirements_table,
@ -42,6 +50,9 @@ def get_boss_name(boss: int):
for key, value in gate_bosses_with_requirements_table.items(): for key, value in gate_bosses_with_requirements_table.items():
if value == boss: if value == boss:
return key return key
for key, value in extra_boss_rush_bosses_table.items():
if value == boss:
return key
def boss_has_requirement(boss: int): def boss_has_requirement(boss: int):
@ -67,3 +78,34 @@ def get_gate_bosses(world, player: int):
bosses: typing.Dict[int, int] = dict(zip(boss_gates, selected_bosses)) bosses: typing.Dict[int, int] = dict(zip(boss_gates, selected_bosses))
return bosses return bosses
def get_boss_rush_bosses(multiworld, player: int):
if multiworld.boss_rush_shuffle[player] == 0:
boss_list_o = list(range(0, 16))
boss_list_s = [5, 2, 0, 10, 8, 4, 3, 1, 6, 13, 7, 11, 9, 15, 14, 12]
return dict(zip(boss_list_o, boss_list_s))
elif multiworld.boss_rush_shuffle[player] == 1:
boss_list_o = list(range(0, 16))
boss_list_s = boss_list_o.copy()
multiworld.random.shuffle(boss_list_s)
return dict(zip(boss_list_o, boss_list_s))
elif multiworld.boss_rush_shuffle[player] == 2:
boss_list_o = list(range(0, 16))
boss_list_s = [multiworld.random.choice(boss_list_o) for i in range(0, 16)]
if 10 not in boss_list_s:
boss_list_s[multiworld.random.randint(0, 15)] = 10
return dict(zip(boss_list_o, boss_list_s))
elif multiworld.boss_rush_shuffle[player] == 3:
boss_list_o = list(range(0, 16))
boss_list_s = [multiworld.random.choice(boss_list_o)] * len(boss_list_o)
if 10 not in boss_list_s:
boss_list_s[multiworld.random.randint(0, 15)] = 10
return dict(zip(boss_list_o, boss_list_s))
else:
return dict()

View File

@ -79,6 +79,9 @@ trap_table = {
ItemName.gravity_trap: ItemData(0xFF0034, False, True), ItemName.gravity_trap: ItemData(0xFF0034, False, True),
ItemName.exposition_trap: ItemData(0xFF0035, False, True), ItemName.exposition_trap: ItemData(0xFF0035, False, True),
#ItemName.darkness_trap: ItemData(0xFF0036, False, True), #ItemName.darkness_trap: ItemData(0xFF0036, False, True),
ItemName.ice_trap: ItemData(0xFF0037, False, True),
ItemName.slow_trap: ItemData(0xFF0038, False, True),
ItemName.cutscene_trap: ItemData(0xFF0039, False, True),
ItemName.pong_trap: ItemData(0xFF0050, False, True), ItemName.pong_trap: ItemData(0xFF0050, False, True),
} }

View File

@ -733,6 +733,487 @@ omochao_location_table = {
LocationName.city_escape_omo_14: 0xFF09A0, LocationName.city_escape_omo_14: 0xFF09A0,
} }
animal_location_table = {
LocationName.city_escape_animal_1: 0xFF0B00,
LocationName.wild_canyon_animal_1: 0xFF0B01,
LocationName.prison_lane_animal_1: 0xFF0B02,
LocationName.metal_harbor_animal_1: 0xFF0B03,
LocationName.green_forest_animal_1: 0xFF0B04,
LocationName.pumpkin_hill_animal_1: 0xFF0B05,
LocationName.mission_street_animal_1: 0xFF0B06,
LocationName.aquatic_mine_animal_1: 0xFF0B07,
LocationName.hidden_base_animal_1: 0xFF0B09,
LocationName.pyramid_cave_animal_1: 0xFF0B0A,
LocationName.death_chamber_animal_1: 0xFF0B0B,
LocationName.eternal_engine_animal_1: 0xFF0B0C,
LocationName.meteor_herd_animal_1: 0xFF0B0D,
LocationName.crazy_gadget_animal_1: 0xFF0B0E,
LocationName.final_rush_animal_1: 0xFF0B0F,
LocationName.iron_gate_animal_1: 0xFF0B10,
LocationName.dry_lagoon_animal_1: 0xFF0B11,
LocationName.sand_ocean_animal_1: 0xFF0B12,
LocationName.radical_highway_animal_1: 0xFF0B13,
LocationName.egg_quarters_animal_1: 0xFF0B14,
LocationName.lost_colony_animal_1: 0xFF0B15,
LocationName.weapons_bed_animal_1: 0xFF0B16,
LocationName.security_hall_animal_1: 0xFF0B17,
LocationName.white_jungle_animal_1: 0xFF0B18,
LocationName.sky_rail_animal_1: 0xFF0B1A,
LocationName.mad_space_animal_1: 0xFF0B1B,
LocationName.cosmic_wall_animal_1: 0xFF0B1C,
LocationName.final_chase_animal_1: 0xFF0B1D,
LocationName.cannon_core_animal_1: 0xFF0B1E,
LocationName.city_escape_animal_2: 0xFF0B20,
LocationName.wild_canyon_animal_2: 0xFF0B21,
LocationName.prison_lane_animal_2: 0xFF0B22,
LocationName.metal_harbor_animal_2: 0xFF0B23,
LocationName.green_forest_animal_2: 0xFF0B24,
LocationName.pumpkin_hill_animal_2: 0xFF0B25,
LocationName.mission_street_animal_2: 0xFF0B26,
LocationName.aquatic_mine_animal_2: 0xFF0B27,
LocationName.hidden_base_animal_2: 0xFF0B29,
LocationName.pyramid_cave_animal_2: 0xFF0B2A,
LocationName.death_chamber_animal_2: 0xFF0B2B,
LocationName.eternal_engine_animal_2: 0xFF0B2C,
LocationName.meteor_herd_animal_2: 0xFF0B2D,
LocationName.crazy_gadget_animal_2: 0xFF0B2E,
LocationName.final_rush_animal_2: 0xFF0B2F,
LocationName.iron_gate_animal_2: 0xFF0B30,
LocationName.dry_lagoon_animal_2: 0xFF0B31,
LocationName.sand_ocean_animal_2: 0xFF0B32,
LocationName.radical_highway_animal_2: 0xFF0B33,
LocationName.egg_quarters_animal_2: 0xFF0B34,
LocationName.lost_colony_animal_2: 0xFF0B35,
LocationName.weapons_bed_animal_2: 0xFF0B36,
LocationName.security_hall_animal_2: 0xFF0B37,
LocationName.white_jungle_animal_2: 0xFF0B38,
LocationName.sky_rail_animal_2: 0xFF0B3A,
LocationName.mad_space_animal_2: 0xFF0B3B,
LocationName.cosmic_wall_animal_2: 0xFF0B3C,
LocationName.final_chase_animal_2: 0xFF0B3D,
LocationName.cannon_core_animal_2: 0xFF0B3E,
LocationName.city_escape_animal_3: 0xFF0B40,
LocationName.wild_canyon_animal_3: 0xFF0B41,
LocationName.prison_lane_animal_3: 0xFF0B42,
LocationName.metal_harbor_animal_3: 0xFF0B43,
LocationName.green_forest_animal_3: 0xFF0B44,
LocationName.pumpkin_hill_animal_3: 0xFF0B45,
LocationName.mission_street_animal_3: 0xFF0B46,
LocationName.aquatic_mine_animal_3: 0xFF0B47,
LocationName.hidden_base_animal_3: 0xFF0B49,
LocationName.pyramid_cave_animal_3: 0xFF0B4A,
LocationName.death_chamber_animal_3: 0xFF0B4B,
LocationName.eternal_engine_animal_3: 0xFF0B4C,
LocationName.meteor_herd_animal_3: 0xFF0B4D,
LocationName.crazy_gadget_animal_3: 0xFF0B4E,
LocationName.final_rush_animal_3: 0xFF0B4F,
LocationName.iron_gate_animal_3: 0xFF0B50,
LocationName.dry_lagoon_animal_3: 0xFF0B51,
LocationName.sand_ocean_animal_3: 0xFF0B52,
LocationName.radical_highway_animal_3: 0xFF0B53,
LocationName.egg_quarters_animal_3: 0xFF0B54,
LocationName.lost_colony_animal_3: 0xFF0B55,
LocationName.weapons_bed_animal_3: 0xFF0B56,
LocationName.security_hall_animal_3: 0xFF0B57,
LocationName.white_jungle_animal_3: 0xFF0B58,
LocationName.sky_rail_animal_3: 0xFF0B5A,
LocationName.mad_space_animal_3: 0xFF0B5B,
LocationName.cosmic_wall_animal_3: 0xFF0B5C,
LocationName.final_chase_animal_3: 0xFF0B5D,
LocationName.cannon_core_animal_3: 0xFF0B5E,
LocationName.city_escape_animal_4: 0xFF0B60,
LocationName.wild_canyon_animal_4: 0xFF0B61,
LocationName.prison_lane_animal_4: 0xFF0B62,
LocationName.metal_harbor_animal_4: 0xFF0B63,
LocationName.green_forest_animal_4: 0xFF0B64,
LocationName.pumpkin_hill_animal_4: 0xFF0B65,
LocationName.mission_street_animal_4: 0xFF0B66,
LocationName.aquatic_mine_animal_4: 0xFF0B67,
LocationName.hidden_base_animal_4: 0xFF0B69,
LocationName.pyramid_cave_animal_4: 0xFF0B6A,
LocationName.death_chamber_animal_4: 0xFF0B6B,
LocationName.eternal_engine_animal_4: 0xFF0B6C,
LocationName.meteor_herd_animal_4: 0xFF0B6D,
LocationName.crazy_gadget_animal_4: 0xFF0B6E,
LocationName.final_rush_animal_4: 0xFF0B6F,
LocationName.iron_gate_animal_4: 0xFF0B70,
LocationName.dry_lagoon_animal_4: 0xFF0B71,
LocationName.sand_ocean_animal_4: 0xFF0B72,
LocationName.radical_highway_animal_4: 0xFF0B73,
LocationName.egg_quarters_animal_4: 0xFF0B74,
LocationName.lost_colony_animal_4: 0xFF0B75,
LocationName.weapons_bed_animal_4: 0xFF0B76,
LocationName.security_hall_animal_4: 0xFF0B77,
LocationName.white_jungle_animal_4: 0xFF0B78,
LocationName.sky_rail_animal_4: 0xFF0B7A,
LocationName.mad_space_animal_4: 0xFF0B7B,
LocationName.cosmic_wall_animal_4: 0xFF0B7C,
LocationName.final_chase_animal_4: 0xFF0B7D,
LocationName.cannon_core_animal_4: 0xFF0B7E,
LocationName.city_escape_animal_5: 0xFF0B80,
LocationName.wild_canyon_animal_5: 0xFF0B81,
LocationName.prison_lane_animal_5: 0xFF0B82,
LocationName.metal_harbor_animal_5: 0xFF0B83,
LocationName.green_forest_animal_5: 0xFF0B84,
LocationName.pumpkin_hill_animal_5: 0xFF0B85,
LocationName.mission_street_animal_5: 0xFF0B86,
LocationName.aquatic_mine_animal_5: 0xFF0B87,
LocationName.hidden_base_animal_5: 0xFF0B89,
LocationName.pyramid_cave_animal_5: 0xFF0B8A,
LocationName.death_chamber_animal_5: 0xFF0B8B,
LocationName.eternal_engine_animal_5: 0xFF0B8C,
LocationName.meteor_herd_animal_5: 0xFF0B8D,
LocationName.crazy_gadget_animal_5: 0xFF0B8E,
LocationName.final_rush_animal_5: 0xFF0B8F,
LocationName.iron_gate_animal_5: 0xFF0B90,
LocationName.dry_lagoon_animal_5: 0xFF0B91,
LocationName.sand_ocean_animal_5: 0xFF0B92,
LocationName.radical_highway_animal_5: 0xFF0B93,
LocationName.egg_quarters_animal_5: 0xFF0B94,
LocationName.lost_colony_animal_5: 0xFF0B95,
LocationName.weapons_bed_animal_5: 0xFF0B96,
LocationName.security_hall_animal_5: 0xFF0B97,
LocationName.white_jungle_animal_5: 0xFF0B98,
LocationName.sky_rail_animal_5: 0xFF0B9A,
LocationName.mad_space_animal_5: 0xFF0B9B,
LocationName.cosmic_wall_animal_5: 0xFF0B9C,
LocationName.final_chase_animal_5: 0xFF0B9D,
LocationName.cannon_core_animal_5: 0xFF0B9E,
LocationName.city_escape_animal_6: 0xFF0BA0,
LocationName.wild_canyon_animal_6: 0xFF0BA1,
LocationName.prison_lane_animal_6: 0xFF0BA2,
LocationName.metal_harbor_animal_6: 0xFF0BA3,
LocationName.green_forest_animal_6: 0xFF0BA4,
LocationName.pumpkin_hill_animal_6: 0xFF0BA5,
LocationName.mission_street_animal_6: 0xFF0BA6,
LocationName.aquatic_mine_animal_6: 0xFF0BA7,
LocationName.hidden_base_animal_6: 0xFF0BA9,
LocationName.pyramid_cave_animal_6: 0xFF0BAA,
LocationName.death_chamber_animal_6: 0xFF0BAB,
LocationName.eternal_engine_animal_6: 0xFF0BAC,
LocationName.meteor_herd_animal_6: 0xFF0BAD,
LocationName.crazy_gadget_animal_6: 0xFF0BAE,
LocationName.final_rush_animal_6: 0xFF0BAF,
LocationName.iron_gate_animal_6: 0xFF0BB0,
LocationName.dry_lagoon_animal_6: 0xFF0BB1,
LocationName.sand_ocean_animal_6: 0xFF0BB2,
LocationName.radical_highway_animal_6: 0xFF0BB3,
LocationName.egg_quarters_animal_6: 0xFF0BB4,
LocationName.lost_colony_animal_6: 0xFF0BB5,
LocationName.weapons_bed_animal_6: 0xFF0BB6,
LocationName.security_hall_animal_6: 0xFF0BB7,
LocationName.white_jungle_animal_6: 0xFF0BB8,
LocationName.sky_rail_animal_6: 0xFF0BBA,
LocationName.mad_space_animal_6: 0xFF0BBB,
LocationName.cosmic_wall_animal_6: 0xFF0BBC,
LocationName.final_chase_animal_6: 0xFF0BBD,
LocationName.cannon_core_animal_6: 0xFF0BBE,
LocationName.city_escape_animal_7: 0xFF0BC0,
LocationName.wild_canyon_animal_7: 0xFF0BC1,
LocationName.prison_lane_animal_7: 0xFF0BC2,
LocationName.metal_harbor_animal_7: 0xFF0BC3,
LocationName.green_forest_animal_7: 0xFF0BC4,
LocationName.pumpkin_hill_animal_7: 0xFF0BC5,
LocationName.mission_street_animal_7: 0xFF0BC6,
LocationName.aquatic_mine_animal_7: 0xFF0BC7,
LocationName.hidden_base_animal_7: 0xFF0BC9,
LocationName.pyramid_cave_animal_7: 0xFF0BCA,
LocationName.death_chamber_animal_7: 0xFF0BCB,
LocationName.eternal_engine_animal_7: 0xFF0BCC,
LocationName.meteor_herd_animal_7: 0xFF0BCD,
LocationName.crazy_gadget_animal_7: 0xFF0BCE,
LocationName.final_rush_animal_7: 0xFF0BCF,
LocationName.iron_gate_animal_7: 0xFF0BD0,
LocationName.dry_lagoon_animal_7: 0xFF0BD1,
LocationName.sand_ocean_animal_7: 0xFF0BD2,
LocationName.radical_highway_animal_7: 0xFF0BD3,
LocationName.egg_quarters_animal_7: 0xFF0BD4,
LocationName.lost_colony_animal_7: 0xFF0BD5,
LocationName.weapons_bed_animal_7: 0xFF0BD6,
LocationName.security_hall_animal_7: 0xFF0BD7,
LocationName.white_jungle_animal_7: 0xFF0BD8,
LocationName.sky_rail_animal_7: 0xFF0BDA,
LocationName.mad_space_animal_7: 0xFF0BDB,
LocationName.cosmic_wall_animal_7: 0xFF0BDC,
LocationName.final_chase_animal_7: 0xFF0BDD,
LocationName.cannon_core_animal_7: 0xFF0BDE,
LocationName.city_escape_animal_8: 0xFF0BE0,
LocationName.wild_canyon_animal_8: 0xFF0BE1,
LocationName.prison_lane_animal_8: 0xFF0BE2,
LocationName.metal_harbor_animal_8: 0xFF0BE3,
LocationName.green_forest_animal_8: 0xFF0BE4,
LocationName.pumpkin_hill_animal_8: 0xFF0BE5,
LocationName.mission_street_animal_8: 0xFF0BE6,
LocationName.aquatic_mine_animal_8: 0xFF0BE7,
LocationName.hidden_base_animal_8: 0xFF0BE9,
LocationName.pyramid_cave_animal_8: 0xFF0BEA,
LocationName.death_chamber_animal_8: 0xFF0BEB,
LocationName.eternal_engine_animal_8: 0xFF0BEC,
LocationName.meteor_herd_animal_8: 0xFF0BED,
LocationName.crazy_gadget_animal_8: 0xFF0BEE,
LocationName.final_rush_animal_8: 0xFF0BEF,
LocationName.iron_gate_animal_8: 0xFF0BF0,
LocationName.dry_lagoon_animal_8: 0xFF0BF1,
LocationName.sand_ocean_animal_8: 0xFF0BF2,
LocationName.radical_highway_animal_8: 0xFF0BF3,
LocationName.egg_quarters_animal_8: 0xFF0BF4,
LocationName.lost_colony_animal_8: 0xFF0BF5,
LocationName.weapons_bed_animal_8: 0xFF0BF6,
LocationName.security_hall_animal_8: 0xFF0BF7,
LocationName.white_jungle_animal_8: 0xFF0BF8,
LocationName.sky_rail_animal_8: 0xFF0BFA,
LocationName.mad_space_animal_8: 0xFF0BFB,
LocationName.cosmic_wall_animal_8: 0xFF0BFC,
LocationName.final_chase_animal_8: 0xFF0BFD,
LocationName.cannon_core_animal_8: 0xFF0BFE,
LocationName.city_escape_animal_9: 0xFF0C00,
LocationName.wild_canyon_animal_9: 0xFF0C01,
LocationName.prison_lane_animal_9: 0xFF0C02,
LocationName.metal_harbor_animal_9: 0xFF0C03,
LocationName.green_forest_animal_9: 0xFF0C04,
LocationName.pumpkin_hill_animal_9: 0xFF0C05,
LocationName.mission_street_animal_9: 0xFF0C06,
LocationName.aquatic_mine_animal_9: 0xFF0C07,
LocationName.hidden_base_animal_9: 0xFF0C09,
LocationName.pyramid_cave_animal_9: 0xFF0C0A,
LocationName.death_chamber_animal_9: 0xFF0C0B,
LocationName.eternal_engine_animal_9: 0xFF0C0C,
LocationName.meteor_herd_animal_9: 0xFF0C0D,
LocationName.crazy_gadget_animal_9: 0xFF0C0E,
LocationName.final_rush_animal_9: 0xFF0C0F,
LocationName.iron_gate_animal_9: 0xFF0C10,
LocationName.dry_lagoon_animal_9: 0xFF0C11,
LocationName.sand_ocean_animal_9: 0xFF0C12,
LocationName.radical_highway_animal_9: 0xFF0C13,
LocationName.egg_quarters_animal_9: 0xFF0C14,
LocationName.lost_colony_animal_9: 0xFF0C15,
LocationName.weapons_bed_animal_9: 0xFF0C16,
LocationName.white_jungle_animal_9: 0xFF0C18,
LocationName.sky_rail_animal_9: 0xFF0C1A,
LocationName.mad_space_animal_9: 0xFF0C1B,
LocationName.cosmic_wall_animal_9: 0xFF0C1C,
LocationName.final_chase_animal_9: 0xFF0C1D,
LocationName.cannon_core_animal_9: 0xFF0C1E,
LocationName.city_escape_animal_10: 0xFF0C20,
LocationName.wild_canyon_animal_10: 0xFF0C21,
LocationName.prison_lane_animal_10: 0xFF0C22,
LocationName.metal_harbor_animal_10: 0xFF0C23,
LocationName.green_forest_animal_10: 0xFF0C24,
LocationName.pumpkin_hill_animal_10: 0xFF0C25,
LocationName.mission_street_animal_10: 0xFF0C26,
LocationName.aquatic_mine_animal_10: 0xFF0C27,
LocationName.hidden_base_animal_10: 0xFF0C29,
LocationName.pyramid_cave_animal_10: 0xFF0C2A,
LocationName.death_chamber_animal_10: 0xFF0C2B,
LocationName.eternal_engine_animal_10: 0xFF0C2C,
LocationName.meteor_herd_animal_10: 0xFF0C2D,
LocationName.crazy_gadget_animal_10: 0xFF0C2E,
LocationName.final_rush_animal_10: 0xFF0C2F,
LocationName.iron_gate_animal_10: 0xFF0C30,
LocationName.dry_lagoon_animal_10: 0xFF0C31,
LocationName.sand_ocean_animal_10: 0xFF0C32,
LocationName.radical_highway_animal_10: 0xFF0C33,
LocationName.egg_quarters_animal_10: 0xFF0C34,
LocationName.lost_colony_animal_10: 0xFF0C35,
LocationName.weapons_bed_animal_10: 0xFF0C36,
LocationName.white_jungle_animal_10: 0xFF0C38,
LocationName.sky_rail_animal_10: 0xFF0C3A,
LocationName.mad_space_animal_10: 0xFF0C3B,
LocationName.cosmic_wall_animal_10: 0xFF0C3C,
LocationName.final_chase_animal_10: 0xFF0C3D,
LocationName.cannon_core_animal_10: 0xFF0C3E,
LocationName.city_escape_animal_11: 0xFF0C40,
LocationName.prison_lane_animal_11: 0xFF0C42,
LocationName.metal_harbor_animal_11: 0xFF0C43,
LocationName.green_forest_animal_11: 0xFF0C44,
LocationName.pumpkin_hill_animal_11: 0xFF0C45,
LocationName.mission_street_animal_11: 0xFF0C46,
LocationName.hidden_base_animal_11: 0xFF0C49,
LocationName.pyramid_cave_animal_11: 0xFF0C4A,
LocationName.eternal_engine_animal_11: 0xFF0C4C,
LocationName.meteor_herd_animal_11: 0xFF0C4D,
LocationName.crazy_gadget_animal_11: 0xFF0C4E,
LocationName.final_rush_animal_11: 0xFF0C4F,
LocationName.iron_gate_animal_11: 0xFF0C50,
LocationName.sand_ocean_animal_11: 0xFF0C52,
LocationName.radical_highway_animal_11: 0xFF0C53,
LocationName.lost_colony_animal_11: 0xFF0C55,
LocationName.weapons_bed_animal_11: 0xFF0C56,
LocationName.white_jungle_animal_11: 0xFF0C58,
LocationName.sky_rail_animal_11: 0xFF0C5A,
LocationName.cosmic_wall_animal_11: 0xFF0C5C,
LocationName.final_chase_animal_11: 0xFF0C5D,
LocationName.cannon_core_animal_11: 0xFF0C5E,
LocationName.city_escape_animal_12: 0xFF0C60,
LocationName.prison_lane_animal_12: 0xFF0C62,
LocationName.metal_harbor_animal_12: 0xFF0C63,
LocationName.green_forest_animal_12: 0xFF0C64,
LocationName.mission_street_animal_12: 0xFF0C66,
LocationName.hidden_base_animal_12: 0xFF0C69,
LocationName.pyramid_cave_animal_12: 0xFF0C6A,
LocationName.eternal_engine_animal_12: 0xFF0C6C,
LocationName.crazy_gadget_animal_12: 0xFF0C6E,
LocationName.final_rush_animal_12: 0xFF0C6F,
LocationName.iron_gate_animal_12: 0xFF0C70,
LocationName.sand_ocean_animal_12: 0xFF0C72,
LocationName.radical_highway_animal_12: 0xFF0C73,
LocationName.lost_colony_animal_12: 0xFF0C75,
LocationName.weapons_bed_animal_12: 0xFF0C76,
LocationName.white_jungle_animal_12: 0xFF0C78,
LocationName.sky_rail_animal_12: 0xFF0C7A,
LocationName.cosmic_wall_animal_12: 0xFF0C7C,
LocationName.final_chase_animal_12: 0xFF0C7D,
LocationName.cannon_core_animal_12: 0xFF0C7E,
LocationName.city_escape_animal_13: 0xFF0C80,
LocationName.prison_lane_animal_13: 0xFF0C82,
LocationName.metal_harbor_animal_13: 0xFF0C83,
LocationName.green_forest_animal_13: 0xFF0C84,
LocationName.mission_street_animal_13: 0xFF0C86,
LocationName.hidden_base_animal_13: 0xFF0C89,
LocationName.pyramid_cave_animal_13: 0xFF0C8A,
LocationName.eternal_engine_animal_13: 0xFF0C8C,
LocationName.crazy_gadget_animal_13: 0xFF0C8E,
LocationName.final_rush_animal_13: 0xFF0C8F,
LocationName.iron_gate_animal_13: 0xFF0C90,
LocationName.sand_ocean_animal_13: 0xFF0C92,
LocationName.radical_highway_animal_13: 0xFF0C93,
LocationName.lost_colony_animal_13: 0xFF0C95,
LocationName.weapons_bed_animal_13: 0xFF0C96,
LocationName.white_jungle_animal_13: 0xFF0C98,
LocationName.sky_rail_animal_13: 0xFF0C9A,
LocationName.cosmic_wall_animal_13: 0xFF0C9C,
LocationName.final_chase_animal_13: 0xFF0C9D,
LocationName.cannon_core_animal_13: 0xFF0C9E,
LocationName.city_escape_animal_14: 0xFF0CA0,
LocationName.prison_lane_animal_14: 0xFF0CA2,
LocationName.metal_harbor_animal_14: 0xFF0CA3,
LocationName.green_forest_animal_14: 0xFF0CA4,
LocationName.mission_street_animal_14: 0xFF0CA6,
LocationName.hidden_base_animal_14: 0xFF0CA9,
LocationName.pyramid_cave_animal_14: 0xFF0CAA,
LocationName.eternal_engine_animal_14: 0xFF0CAC,
LocationName.crazy_gadget_animal_14: 0xFF0CAE,
LocationName.final_rush_animal_14: 0xFF0CAF,
LocationName.iron_gate_animal_14: 0xFF0CB0,
LocationName.sand_ocean_animal_14: 0xFF0CB2,
LocationName.radical_highway_animal_14: 0xFF0CB3,
LocationName.lost_colony_animal_14: 0xFF0CB5,
LocationName.weapons_bed_animal_14: 0xFF0CB6,
LocationName.white_jungle_animal_14: 0xFF0CB8,
LocationName.sky_rail_animal_14: 0xFF0CBA,
LocationName.cosmic_wall_animal_14: 0xFF0CBC,
LocationName.final_chase_animal_14: 0xFF0CBD,
LocationName.cannon_core_animal_14: 0xFF0CBE,
LocationName.city_escape_animal_15: 0xFF0CC0,
LocationName.prison_lane_animal_15: 0xFF0CC2,
LocationName.green_forest_animal_15: 0xFF0CC4,
LocationName.mission_street_animal_15: 0xFF0CC6,
LocationName.hidden_base_animal_15: 0xFF0CC9,
LocationName.pyramid_cave_animal_15: 0xFF0CCA,
LocationName.eternal_engine_animal_15: 0xFF0CCC,
LocationName.crazy_gadget_animal_15: 0xFF0CCE,
LocationName.final_rush_animal_15: 0xFF0CCF,
LocationName.iron_gate_animal_15: 0xFF0CD0,
LocationName.sand_ocean_animal_15: 0xFF0CD2,
LocationName.radical_highway_animal_15: 0xFF0CD3,
LocationName.weapons_bed_animal_15: 0xFF0CD6,
LocationName.white_jungle_animal_15: 0xFF0CD8,
LocationName.sky_rail_animal_15: 0xFF0CDA,
LocationName.cosmic_wall_animal_15: 0xFF0CDC,
LocationName.final_chase_animal_15: 0xFF0CDD,
LocationName.cannon_core_animal_15: 0xFF0CDE,
LocationName.city_escape_animal_16: 0xFF0CE0,
LocationName.green_forest_animal_16: 0xFF0CE4,
LocationName.mission_street_animal_16: 0xFF0CE6,
LocationName.pyramid_cave_animal_16: 0xFF0CEA,
LocationName.crazy_gadget_animal_16: 0xFF0CEE,
LocationName.final_rush_animal_16: 0xFF0CEF,
LocationName.radical_highway_animal_16: 0xFF0CF3,
LocationName.white_jungle_animal_16: 0xFF0CF8,
LocationName.sky_rail_animal_16: 0xFF0CFA,
LocationName.final_chase_animal_16: 0xFF0CFD,
LocationName.cannon_core_animal_16: 0xFF0CFE,
LocationName.city_escape_animal_17: 0xFF0D00,
LocationName.green_forest_animal_17: 0xFF0D04,
LocationName.pyramid_cave_animal_17: 0xFF0D0A,
LocationName.radical_highway_animal_17: 0xFF0D13,
LocationName.sky_rail_animal_17: 0xFF0D1A,
LocationName.final_chase_animal_17: 0xFF0D1D,
LocationName.cannon_core_animal_17: 0xFF0D1E,
LocationName.city_escape_animal_18: 0xFF0D20,
LocationName.green_forest_animal_18: 0xFF0D24,
LocationName.pyramid_cave_animal_18: 0xFF0D2A,
LocationName.radical_highway_animal_18: 0xFF0D33,
LocationName.sky_rail_animal_18: 0xFF0D3A,
LocationName.cannon_core_animal_18: 0xFF0D3E,
LocationName.city_escape_animal_19: 0xFF0D40,
LocationName.pyramid_cave_animal_19: 0xFF0D4A,
LocationName.radical_highway_animal_19: 0xFF0D53,
LocationName.sky_rail_animal_19: 0xFF0D5A,
LocationName.cannon_core_animal_19: 0xFF0D5E,
LocationName.city_escape_animal_20: 0xFF0D60,
LocationName.radical_highway_animal_20: 0xFF0D73,
LocationName.sky_rail_animal_20: 0xFF0D7A,
}
boss_gate_location_table = { boss_gate_location_table = {
LocationName.gate_1_boss: 0xFF0100, LocationName.gate_1_boss: 0xFF0100,
LocationName.gate_2_boss: 0xFF0101, LocationName.gate_2_boss: 0xFF0101,
@ -741,6 +1222,25 @@ boss_gate_location_table = {
LocationName.gate_5_boss: 0xFF0104, LocationName.gate_5_boss: 0xFF0104,
} }
boss_rush_location_table = {
LocationName.boss_rush_1: 0xFF0105,
LocationName.boss_rush_2: 0xFF0106,
LocationName.boss_rush_3: 0xFF0107,
LocationName.boss_rush_4: 0xFF0108,
LocationName.boss_rush_5: 0xFF0109,
LocationName.boss_rush_6: 0xFF010A,
LocationName.boss_rush_7: 0xFF010B,
LocationName.boss_rush_8: 0xFF010C,
LocationName.boss_rush_9: 0xFF010D,
LocationName.boss_rush_10: 0xFF010E,
LocationName.boss_rush_11: 0xFF010F,
LocationName.boss_rush_12: 0xFF0110,
LocationName.boss_rush_13: 0xFF0111,
LocationName.boss_rush_14: 0xFF0112,
LocationName.boss_rush_15: 0xFF0113,
LocationName.boss_rush_16: 0xFF0114,
}
chao_garden_beginner_location_table = { chao_garden_beginner_location_table = {
LocationName.chao_race_crab_pool_1: 0xFF0200, LocationName.chao_race_crab_pool_1: 0xFF0200,
LocationName.chao_race_crab_pool_2: 0xFF0201, LocationName.chao_race_crab_pool_2: 0xFF0201,
@ -862,6 +1362,10 @@ green_hill_chao_location_table = {
LocationName.green_hill_chao_1: 0xFF041F, LocationName.green_hill_chao_1: 0xFF041F,
} }
green_hill_animal_location_table = {
#LocationName.green_hill_animal_1: 0xFF0B1F, # Disabled for technical reasons, may return
}
final_boss_location_table = { final_boss_location_table = {
# LocationName.biolizard: 0xFF003F, # LocationName.biolizard: 0xFF003F,
LocationName.finalhazard: 0xFF005F, LocationName.finalhazard: 0xFF005F,
@ -875,11 +1379,13 @@ all_locations = {
**mission_location_table, **mission_location_table,
**upgrade_location_table, **upgrade_location_table,
**boss_gate_location_table, **boss_gate_location_table,
**boss_rush_location_table,
**chao_key_location_table, **chao_key_location_table,
**pipe_location_table, **pipe_location_table,
**hidden_whistle_location_table, **hidden_whistle_location_table,
**beetle_location_table, **beetle_location_table,
**omochao_location_table, **omochao_location_table,
**animal_location_table,
**chao_garden_beginner_location_table, **chao_garden_beginner_location_table,
**chao_garden_intermediate_location_table, **chao_garden_intermediate_location_table,
**chao_garden_expert_location_table, **chao_garden_expert_location_table,
@ -889,6 +1395,7 @@ all_locations = {
**kart_race_mini_location_table, **kart_race_mini_location_table,
**green_hill_location_table, **green_hill_location_table,
**green_hill_chao_location_table, **green_hill_chao_location_table,
**green_hill_animal_location_table,
**final_boss_location_table, **final_boss_location_table,
**grand_prix_location_table, **grand_prix_location_table,
} }
@ -975,6 +1482,9 @@ def setup_locations(world: MultiWorld, player: int, mission_map: typing.Dict[int
if world.omosanity[player]: if world.omosanity[player]:
location_table.update({**omochao_location_table}) location_table.update({**omochao_location_table})
if world.animalsanity[player]:
location_table.update({**animal_location_table})
if world.kart_race_checks[player] == 2: if world.kart_race_checks[player] == 2:
location_table.update({**kart_race_beginner_location_table}) location_table.update({**kart_race_beginner_location_table})
location_table.update({**kart_race_standard_location_table}) location_table.update({**kart_race_standard_location_table})
@ -982,15 +1492,21 @@ def setup_locations(world: MultiWorld, player: int, mission_map: typing.Dict[int
elif world.kart_race_checks[player] == 1: elif world.kart_race_checks[player] == 1:
location_table.update({**kart_race_mini_location_table}) location_table.update({**kart_race_mini_location_table})
if world.goal[player].value == 0 or world.goal[player].value == 2: if world.goal[player].value in [0, 2, 4, 5, 6]:
location_table.update({**final_boss_location_table}) location_table.update({**final_boss_location_table})
if world.goal[player].value == 1 or world.goal[player].value == 2: if world.goal[player].value in [1, 2]:
location_table.update({**green_hill_location_table}) location_table.update({**green_hill_location_table})
if world.keysanity[player]: if world.keysanity[player]:
location_table.update({**green_hill_chao_location_table}) location_table.update({**green_hill_chao_location_table})
if world.animalsanity[player]:
location_table.update({**green_hill_animal_location_table})
if world.goal[player].value in [4, 5, 6]:
location_table.update({**boss_rush_location_table})
if world.chao_garden_difficulty[player].value >= 1: if world.chao_garden_difficulty[player].value >= 1:
chao_location_table.update({**chao_garden_beginner_location_table}) chao_location_table.update({**chao_garden_beginner_location_table})
if world.chao_garden_difficulty[player].value >= 2: if world.chao_garden_difficulty[player].value >= 2:

View File

@ -190,7 +190,7 @@ stage_name_prefixes: typing.List[str] = [
"Mad Space - ", "Mad Space - ",
"Cosmic Wall - ", "Cosmic Wall - ",
"Final Chase - ", "Final Chase - ",
"Cannon Core - ", "Cannon's Core - ",
] ]
def get_mission_count_table(multiworld: MultiWorld, player: int): def get_mission_count_table(multiworld: MultiWorld, player: int):
@ -290,9 +290,13 @@ def get_mission_table(multiworld: MultiWorld, player: int):
# The first mission must be M1, M2, M3, or M4 # The first mission must be M1, M2, M3, or M4
first_mission = 1 first_mission = 1
first_mission_options = [1, 2, 3]
if not multiworld.animalsanity[player]:
first_mission_options.append(4)
if multiworld.mission_shuffle[player]: if multiworld.mission_shuffle[player]:
first_mission = multiworld.random.choice([mission for mission in level_active_missions if mission in [1, 2, 3, 4]]) first_mission = multiworld.random.choice([mission for mission in level_active_missions if mission in first_mission_options])
level_active_missions.remove(first_mission) level_active_missions.remove(first_mission)

View File

@ -51,6 +51,10 @@ tiny_trap = "Tiny Trap"
gravity_trap = "Gravity Trap" gravity_trap = "Gravity Trap"
exposition_trap = "Exposition Trap" exposition_trap = "Exposition Trap"
darkness_trap = "Darkness Trap" darkness_trap = "Darkness Trap"
ice_trap = "Ice Trap"
slow_trap = "Slow Trap"
cutscene_trap = "Cutscene Trap"
pong_trap = "Pong Trap" pong_trap = "Pong Trap"
white_emerald = "White Chaos Emerald" white_emerald = "White Chaos Emerald"

File diff suppressed because it is too large Load Diff

View File

@ -10,14 +10,29 @@ class Goal(Choice):
Chaos Emerald Hunt: Find the Seven Chaos Emeralds and reach Green Hill Zone 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 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) Grand Prix: Win every race in Kart Race Mode (all standard levels are disabled)
Boss Rush: Beat all of the bosses in the Boss Rush, ending with Finalhazard
Cannon's Core Boss Rush: Beat Cannon's Core, then beat all of the bosses in the Boss Rush, ending with Finalhazard
Boss Rush Chaos Emerald Hunt: Find the Seven Chaos Emeralds, then beat all of the bosses in the Boss Rush, ending with Finalhazard
""" """
display_name = "Goal" display_name = "Goal"
option_biolizard = 0 option_biolizard = 0
option_chaos_emerald_hunt = 1 option_chaos_emerald_hunt = 1
option_finalhazard_chaos_emerald_hunt = 2 option_finalhazard_chaos_emerald_hunt = 2
option_grand_prix = 3 option_grand_prix = 3
option_boss_rush = 4
option_cannons_core_boss_rush = 5
option_boss_rush_chaos_emerald_hunt = 6
default = 0 default = 0
@classmethod
def get_option_name(cls, value) -> str:
if cls.auto_display_name and value == 5:
return "Cannon's Core Boss Rush"
elif cls.auto_display_name:
return cls.name_lookup[value].replace("_", " ").title()
else:
return cls.name_lookup[value]
class MissionShuffle(Toggle): class MissionShuffle(Toggle):
""" """
@ -26,6 +41,22 @@ class MissionShuffle(Toggle):
display_name = "Mission Shuffle" display_name = "Mission Shuffle"
class BossRushShuffle(Choice):
"""
Determines how bosses in Boss Rush Mode are shuffled
Vanilla: Bosses appear in the Vanilla ordering
Shuffled: The same bosses appear, but in a random order
Chaos: Each boss is randomly chosen separately (one will always be King Boom Boo)
Singularity: One boss is chosen and placed in every slot (one will always be replaced with King Boom Boo)
"""
display_name = "Boss Rush Shuffle"
option_vanilla = 0
option_shuffled = 1
option_chaos = 2
option_singularity = 3
default = 0
class BaseTrapWeight(Choice): class BaseTrapWeight(Choice):
""" """
Base Class for Trap Weights Base Class for Trap Weights
@ -86,6 +117,27 @@ class DarknessTrapWeight(BaseTrapWeight):
display_name = "Darkness Trap Weight" display_name = "Darkness Trap Weight"
class IceTrapWeight(BaseTrapWeight):
"""
Likelihood of a receiving a trap which makes the world slippery
"""
display_name = "Ice Trap Weight"
class SlowTrapWeight(BaseTrapWeight):
"""
Likelihood of a receiving a trap which makes you gotta go slow
"""
display_name = "Slow Trap Weight"
class CutsceneTrapWeight(BaseTrapWeight):
"""
Likelihood of a receiving a trap which makes you watch an unskippable cutscene
"""
display_name = "Cutscene Trap Weight"
class PongTrapWeight(BaseTrapWeight): class PongTrapWeight(BaseTrapWeight):
""" """
Likelihood of receiving a trap which forces you to play a Pong minigame Likelihood of receiving a trap which forces you to play a Pong minigame
@ -124,25 +176,10 @@ class TrapFillPercentage(Range):
default = 0 default = 0
class IncludeMissions(Range):
"""
Allows logic to place items in a range of Missions for each level
Each mission setting includes lower settings
1: Base Story Missions
2: 100 Ring Missions
3: Lost Chao Missions
4: Timer Missions
5: Hard Mode Missions
"""
display_name = "Include Missions"
range_start = 1
range_end = 5
default = 2
class Keysanity(Toggle): class Keysanity(Toggle):
""" """
Determines whether picking up Chao Keys grants checks Determines whether picking up Chao Keys grants checks
(86 Locations)
""" """
display_name = "Keysanity" display_name = "Keysanity"
@ -151,9 +188,9 @@ class Whistlesanity(Choice):
""" """
Determines whether whistling at various spots grants checks Determines whether whistling at various spots grants checks
None: No Whistle Spots grant checks None: No Whistle Spots grant checks
Pipes: Whistling at Pipes grants checks Pipes: Whistling at Pipes grants checks (97 Locations)
Hidden: Whistling at Hidden Whistle Spots grants checks Hidden: Whistling at Hidden Whistle Spots grants checks (32 Locations)
Both: Whistling at both Pipes and Hidden Whistle Spots grants checks Both: Whistling at both Pipes and Hidden Whistle Spots grants checks (129 Locations)
""" """
display_name = "Whistlesanity" display_name = "Whistlesanity"
option_none = 0 option_none = 0
@ -166,6 +203,7 @@ class Whistlesanity(Choice):
class Beetlesanity(Toggle): class Beetlesanity(Toggle):
""" """
Determines whether destroying Gold Beetles grants checks Determines whether destroying Gold Beetles grants checks
(27 Locations)
""" """
display_name = "Beetlesanity" display_name = "Beetlesanity"
@ -173,10 +211,19 @@ class Beetlesanity(Toggle):
class Omosanity(Toggle): class Omosanity(Toggle):
""" """
Determines whether activating Omochao grants checks Determines whether activating Omochao grants checks
(192 Locations)
""" """
display_name = "Omosanity" display_name = "Omosanity"
class Animalsanity(Toggle):
"""
Determines whether picking up counted small animals grants checks
(420 Locations)
"""
display_name = "Animalsanity"
class KartRaceChecks(Choice): class KartRaceChecks(Choice):
""" """
Determines whether Kart Race Mode grants checks Determines whether Kart Race Mode grants checks
@ -236,6 +283,18 @@ class LevelGateCosts(Choice):
default = 2 default = 2
class MaximumEmblemCap(Range):
"""
Determines the maximum number of emblems that can be in the item pool.
If fewer available locations exist in the pool than this number, the number of available locations will be used instead.
Gate and Cannon's Core costs will be calculated based off of that number.
"""
display_name = "Max Emblem Cap"
range_start = 50
range_end = 500
default = 180
class RequiredRank(Choice): class RequiredRank(Choice):
""" """
Determines what minimum Rank is required to send a check for a mission Determines what minimum Rank is required to send a check for a mission
@ -254,8 +313,8 @@ class ChaoGardenDifficulty(Choice):
Determines the number of chao garden difficulty levels included. Easier difficulty settings means fewer chao garden checks Determines the number of chao garden difficulty levels included. Easier difficulty settings means fewer chao garden checks
None: No Chao Garden Activities have checks None: No Chao Garden Activities have checks
Beginner: Beginner Races Beginner: Beginner Races
Intermediate: Beginner and Jewel Races Intermediate: Beginner, Challenge, Hero, and Dark Races
Expert: Beginner, Jewel, Challenge, Hero, and Dark Races Expert: Beginner, Challenge, Hero, Dark and Jewel Races
""" """
display_name = "Chao Garden Difficulty" display_name = "Chao Garden Difficulty"
option_none = 0 option_none = 0
@ -287,7 +346,7 @@ class ChaoRaceChecks(Choice):
class RequiredCannonsCoreMissions(Choice): class RequiredCannonsCoreMissions(Choice):
""" """
Determines how many Cannon's Core missions must be completed to unlock the Biolizard (for the "Biolizard" goal) Determines how many Cannon's Core missions must be completed (for Biolizard or Cannon's Core goals)
First: Only the first mission must be completed First: Only the first mission must be completed
All Active: All active Cannon's Core missions must be completed All Active: All active Cannon's Core missions must be completed
""" """
@ -502,6 +561,13 @@ class RingLoss(Choice):
return cls.name_lookup[value] return cls.name_lookup[value]
class RingLink(Toggle):
"""
Whether your in-level ring gain/loss is linked to other players
"""
display_name = "Ring Link"
class SADXMusic(Choice): class SADXMusic(Choice):
""" """
Whether the randomizer will include Sonic Adventure DX Music in the music pool Whether the randomizer will include Sonic Adventure DX Music in the music pool
@ -527,7 +593,7 @@ class SADXMusic(Choice):
class MusicShuffle(Choice): class MusicShuffle(Choice):
""" """
What type of Music Shuffle is used What type of Music Shuffle is used
Off: No music is shuffled. None: No music is shuffled.
Levels: Level music is shuffled. Levels: Level music is shuffled.
Full: Level, Menu, and Additional music is shuffled. Full: Level, Menu, and Additional music is shuffled.
Singularity: Level, Menu, and Additional music is all replaced with a single random song. Singularity: Level, Menu, and Additional music is all replaced with a single random song.
@ -540,6 +606,24 @@ class MusicShuffle(Choice):
default = 0 default = 0
class VoiceShuffle(Choice):
"""
What type of Voice Shuffle is used
None: No voices are shuffled.
Shuffled: Voices are shuffled.
Rude: Voices are shuffled, but some are replaced with rude words.
Chao: All voices are replaced with chao sounds.
Singularity: All voices are replaced with a single random voice.
"""
display_name = "Voice Shuffle Type"
option_none = 0
option_shuffled = 1
option_rude = 2
option_chao = 3
option_singularity = 4
default = 0
class Narrator(Choice): class Narrator(Choice):
""" """
Which menu narrator is used Which menu narrator is used
@ -574,10 +658,12 @@ class LogicDifficulty(Choice):
sa2b_options: typing.Dict[str, type(Option)] = { sa2b_options: typing.Dict[str, type(Option)] = {
"goal": Goal, "goal": Goal,
"mission_shuffle": MissionShuffle, "mission_shuffle": MissionShuffle,
"boss_rush_shuffle": BossRushShuffle,
"keysanity": Keysanity, "keysanity": Keysanity,
"whistlesanity": Whistlesanity, "whistlesanity": Whistlesanity,
"beetlesanity": Beetlesanity, "beetlesanity": Beetlesanity,
"omosanity": Omosanity, "omosanity": Omosanity,
"animalsanity": Animalsanity,
"kart_race_checks": KartRaceChecks, "kart_race_checks": KartRaceChecks,
"required_rank": RequiredRank, "required_rank": RequiredRank,
"emblem_percentage_for_cannons_core": EmblemPercentageForCannonsCore, "emblem_percentage_for_cannons_core": EmblemPercentageForCannonsCore,
@ -585,6 +671,7 @@ sa2b_options: typing.Dict[str, type(Option)] = {
"number_of_level_gates": NumberOfLevelGates, "number_of_level_gates": NumberOfLevelGates,
"level_gate_distribution": LevelGateDistribution, "level_gate_distribution": LevelGateDistribution,
"level_gate_costs": LevelGateCosts, "level_gate_costs": LevelGateCosts,
"max_emblem_cap": MaximumEmblemCap,
"chao_garden_difficulty": ChaoGardenDifficulty, "chao_garden_difficulty": ChaoGardenDifficulty,
"include_chao_karate": IncludeChaoKarate, "include_chao_karate": IncludeChaoKarate,
"chao_race_checks": ChaoRaceChecks, "chao_race_checks": ChaoRaceChecks,
@ -597,11 +684,16 @@ sa2b_options: typing.Dict[str, type(Option)] = {
"gravity_trap_weight": GravityTrapWeight, "gravity_trap_weight": GravityTrapWeight,
"exposition_trap_weight": ExpositionTrapWeight, "exposition_trap_weight": ExpositionTrapWeight,
#"darkness_trap_weight": DarknessTrapWeight, #"darkness_trap_weight": DarknessTrapWeight,
"ice_trap_weight": IceTrapWeight,
"slow_trap_weight": SlowTrapWeight,
"cutscene_trap_weight": CutsceneTrapWeight,
"pong_trap_weight": PongTrapWeight, "pong_trap_weight": PongTrapWeight,
"minigame_trap_difficulty": MinigameTrapDifficulty, "minigame_trap_difficulty": MinigameTrapDifficulty,
"ring_loss": RingLoss, "ring_loss": RingLoss,
"ring_link": RingLink,
"sadx_music": SADXMusic, "sadx_music": SADXMusic,
"music_shuffle": MusicShuffle, "music_shuffle": MusicShuffle,
"voice_shuffle": VoiceShuffle,
"narrator": Narrator, "narrator": Narrator,
"logic_difficulty": LogicDifficulty, "logic_difficulty": LogicDifficulty,
"speed_mission_count": SpeedMissionCount, "speed_mission_count": SpeedMissionCount,

View File

@ -149,6 +149,26 @@ def create_regions(world, player: int, active_locations):
LocationName.city_escape_omo_13, LocationName.city_escape_omo_13,
LocationName.city_escape_omo_14, LocationName.city_escape_omo_14,
LocationName.city_escape_beetle, LocationName.city_escape_beetle,
LocationName.city_escape_animal_1,
LocationName.city_escape_animal_2,
LocationName.city_escape_animal_3,
LocationName.city_escape_animal_4,
LocationName.city_escape_animal_5,
LocationName.city_escape_animal_6,
LocationName.city_escape_animal_7,
LocationName.city_escape_animal_8,
LocationName.city_escape_animal_9,
LocationName.city_escape_animal_10,
LocationName.city_escape_animal_11,
LocationName.city_escape_animal_12,
LocationName.city_escape_animal_13,
LocationName.city_escape_animal_14,
LocationName.city_escape_animal_15,
LocationName.city_escape_animal_16,
LocationName.city_escape_animal_17,
LocationName.city_escape_animal_18,
LocationName.city_escape_animal_19,
LocationName.city_escape_animal_20,
LocationName.city_escape_upgrade, LocationName.city_escape_upgrade,
] ]
city_escape_region = create_region(world, player, active_locations, LocationName.city_escape_region, city_escape_region = create_region(world, player, active_locations, LocationName.city_escape_region,
@ -170,6 +190,20 @@ def create_regions(world, player: int, active_locations):
LocationName.metal_harbor_omo_4, LocationName.metal_harbor_omo_4,
LocationName.metal_harbor_omo_5, LocationName.metal_harbor_omo_5,
LocationName.metal_harbor_beetle, LocationName.metal_harbor_beetle,
LocationName.metal_harbor_animal_1,
LocationName.metal_harbor_animal_2,
LocationName.metal_harbor_animal_3,
LocationName.metal_harbor_animal_4,
LocationName.metal_harbor_animal_5,
LocationName.metal_harbor_animal_6,
LocationName.metal_harbor_animal_7,
LocationName.metal_harbor_animal_8,
LocationName.metal_harbor_animal_9,
LocationName.metal_harbor_animal_10,
LocationName.metal_harbor_animal_11,
LocationName.metal_harbor_animal_12,
LocationName.metal_harbor_animal_13,
LocationName.metal_harbor_animal_14,
LocationName.metal_harbor_upgrade, LocationName.metal_harbor_upgrade,
] ]
metal_harbor_region = create_region(world, player, active_locations, LocationName.metal_harbor_region, metal_harbor_region = create_region(world, player, active_locations, LocationName.metal_harbor_region,
@ -191,6 +225,24 @@ def create_regions(world, player: int, active_locations):
LocationName.green_forest_hidden_3, LocationName.green_forest_hidden_3,
LocationName.green_forest_hidden_4, LocationName.green_forest_hidden_4,
LocationName.green_forest_beetle, LocationName.green_forest_beetle,
LocationName.green_forest_animal_1,
LocationName.green_forest_animal_2,
LocationName.green_forest_animal_3,
LocationName.green_forest_animal_4,
LocationName.green_forest_animal_5,
LocationName.green_forest_animal_6,
LocationName.green_forest_animal_7,
LocationName.green_forest_animal_8,
LocationName.green_forest_animal_9,
LocationName.green_forest_animal_10,
LocationName.green_forest_animal_11,
LocationName.green_forest_animal_12,
LocationName.green_forest_animal_13,
LocationName.green_forest_animal_14,
LocationName.green_forest_animal_15,
LocationName.green_forest_animal_16,
LocationName.green_forest_animal_17,
LocationName.green_forest_animal_18,
LocationName.green_forest_upgrade, LocationName.green_forest_upgrade,
] ]
green_forest_region = create_region(world, player, active_locations, LocationName.green_forest_region, green_forest_region = create_region(world, player, active_locations, LocationName.green_forest_region,
@ -214,6 +266,25 @@ def create_regions(world, player: int, active_locations):
LocationName.pyramid_cave_omo_3, LocationName.pyramid_cave_omo_3,
LocationName.pyramid_cave_omo_4, LocationName.pyramid_cave_omo_4,
LocationName.pyramid_cave_beetle, LocationName.pyramid_cave_beetle,
LocationName.pyramid_cave_animal_1,
LocationName.pyramid_cave_animal_2,
LocationName.pyramid_cave_animal_3,
LocationName.pyramid_cave_animal_4,
LocationName.pyramid_cave_animal_5,
LocationName.pyramid_cave_animal_6,
LocationName.pyramid_cave_animal_7,
LocationName.pyramid_cave_animal_8,
LocationName.pyramid_cave_animal_9,
LocationName.pyramid_cave_animal_10,
LocationName.pyramid_cave_animal_11,
LocationName.pyramid_cave_animal_12,
LocationName.pyramid_cave_animal_13,
LocationName.pyramid_cave_animal_14,
LocationName.pyramid_cave_animal_15,
LocationName.pyramid_cave_animal_16,
LocationName.pyramid_cave_animal_17,
LocationName.pyramid_cave_animal_18,
LocationName.pyramid_cave_animal_19,
LocationName.pyramid_cave_upgrade, LocationName.pyramid_cave_upgrade,
] ]
pyramid_cave_region = create_region(world, player, active_locations, LocationName.pyramid_cave_region, pyramid_cave_region = create_region(world, player, active_locations, LocationName.pyramid_cave_region,
@ -247,6 +318,22 @@ def create_regions(world, player: int, active_locations):
LocationName.crazy_gadget_omo_12, LocationName.crazy_gadget_omo_12,
LocationName.crazy_gadget_omo_13, LocationName.crazy_gadget_omo_13,
LocationName.crazy_gadget_beetle, LocationName.crazy_gadget_beetle,
LocationName.crazy_gadget_animal_1,
LocationName.crazy_gadget_animal_2,
LocationName.crazy_gadget_animal_3,
LocationName.crazy_gadget_animal_4,
LocationName.crazy_gadget_animal_5,
LocationName.crazy_gadget_animal_6,
LocationName.crazy_gadget_animal_7,
LocationName.crazy_gadget_animal_8,
LocationName.crazy_gadget_animal_9,
LocationName.crazy_gadget_animal_10,
LocationName.crazy_gadget_animal_11,
LocationName.crazy_gadget_animal_12,
LocationName.crazy_gadget_animal_13,
LocationName.crazy_gadget_animal_14,
LocationName.crazy_gadget_animal_15,
LocationName.crazy_gadget_animal_16,
LocationName.crazy_gadget_upgrade, LocationName.crazy_gadget_upgrade,
] ]
crazy_gadget_region = create_region(world, player, active_locations, LocationName.crazy_gadget_region, crazy_gadget_region = create_region(world, player, active_locations, LocationName.crazy_gadget_region,
@ -267,6 +354,22 @@ def create_regions(world, player: int, active_locations):
LocationName.final_rush_omo_2, LocationName.final_rush_omo_2,
LocationName.final_rush_omo_3, LocationName.final_rush_omo_3,
LocationName.final_rush_beetle, LocationName.final_rush_beetle,
LocationName.final_rush_animal_1,
LocationName.final_rush_animal_2,
LocationName.final_rush_animal_3,
LocationName.final_rush_animal_4,
LocationName.final_rush_animal_5,
LocationName.final_rush_animal_6,
LocationName.final_rush_animal_7,
LocationName.final_rush_animal_8,
LocationName.final_rush_animal_9,
LocationName.final_rush_animal_10,
LocationName.final_rush_animal_11,
LocationName.final_rush_animal_12,
LocationName.final_rush_animal_13,
LocationName.final_rush_animal_14,
LocationName.final_rush_animal_15,
LocationName.final_rush_animal_16,
LocationName.final_rush_upgrade, LocationName.final_rush_upgrade,
] ]
final_rush_region = create_region(world, player, active_locations, LocationName.final_rush_region, final_rush_region = create_region(world, player, active_locations, LocationName.final_rush_region,
@ -298,6 +401,21 @@ def create_regions(world, player: int, active_locations):
LocationName.prison_lane_omo_9, LocationName.prison_lane_omo_9,
LocationName.prison_lane_omo_10, LocationName.prison_lane_omo_10,
LocationName.prison_lane_beetle, LocationName.prison_lane_beetle,
LocationName.prison_lane_animal_1,
LocationName.prison_lane_animal_2,
LocationName.prison_lane_animal_3,
LocationName.prison_lane_animal_4,
LocationName.prison_lane_animal_5,
LocationName.prison_lane_animal_6,
LocationName.prison_lane_animal_7,
LocationName.prison_lane_animal_8,
LocationName.prison_lane_animal_9,
LocationName.prison_lane_animal_10,
LocationName.prison_lane_animal_11,
LocationName.prison_lane_animal_12,
LocationName.prison_lane_animal_13,
LocationName.prison_lane_animal_14,
LocationName.prison_lane_animal_15,
LocationName.prison_lane_upgrade, LocationName.prison_lane_upgrade,
] ]
prison_lane_region = create_region(world, player, active_locations, LocationName.prison_lane_region, prison_lane_region = create_region(world, player, active_locations, LocationName.prison_lane_region,
@ -328,6 +446,22 @@ def create_regions(world, player: int, active_locations):
LocationName.mission_street_omo_7, LocationName.mission_street_omo_7,
LocationName.mission_street_omo_8, LocationName.mission_street_omo_8,
LocationName.mission_street_beetle, LocationName.mission_street_beetle,
LocationName.mission_street_animal_1,
LocationName.mission_street_animal_2,
LocationName.mission_street_animal_3,
LocationName.mission_street_animal_4,
LocationName.mission_street_animal_5,
LocationName.mission_street_animal_6,
LocationName.mission_street_animal_7,
LocationName.mission_street_animal_8,
LocationName.mission_street_animal_9,
LocationName.mission_street_animal_10,
LocationName.mission_street_animal_11,
LocationName.mission_street_animal_12,
LocationName.mission_street_animal_13,
LocationName.mission_street_animal_14,
LocationName.mission_street_animal_15,
LocationName.mission_street_animal_16,
LocationName.mission_street_upgrade, LocationName.mission_street_upgrade,
] ]
mission_street_region = create_region(world, player, active_locations, LocationName.mission_street_region, mission_street_region = create_region(world, player, active_locations, LocationName.mission_street_region,
@ -361,6 +495,21 @@ def create_regions(world, player: int, active_locations):
LocationName.hidden_base_omo_3, LocationName.hidden_base_omo_3,
LocationName.hidden_base_omo_4, LocationName.hidden_base_omo_4,
LocationName.hidden_base_beetle, LocationName.hidden_base_beetle,
LocationName.hidden_base_animal_1,
LocationName.hidden_base_animal_2,
LocationName.hidden_base_animal_3,
LocationName.hidden_base_animal_4,
LocationName.hidden_base_animal_5,
LocationName.hidden_base_animal_6,
LocationName.hidden_base_animal_7,
LocationName.hidden_base_animal_8,
LocationName.hidden_base_animal_9,
LocationName.hidden_base_animal_10,
LocationName.hidden_base_animal_11,
LocationName.hidden_base_animal_12,
LocationName.hidden_base_animal_13,
LocationName.hidden_base_animal_14,
LocationName.hidden_base_animal_15,
LocationName.hidden_base_upgrade, LocationName.hidden_base_upgrade,
] ]
hidden_base_region = create_region(world, player, active_locations, LocationName.hidden_base_region, hidden_base_region = create_region(world, player, active_locations, LocationName.hidden_base_region,
@ -393,6 +542,21 @@ def create_regions(world, player: int, active_locations):
LocationName.eternal_engine_omo_11, LocationName.eternal_engine_omo_11,
LocationName.eternal_engine_omo_12, LocationName.eternal_engine_omo_12,
LocationName.eternal_engine_beetle, LocationName.eternal_engine_beetle,
LocationName.eternal_engine_animal_1,
LocationName.eternal_engine_animal_2,
LocationName.eternal_engine_animal_3,
LocationName.eternal_engine_animal_4,
LocationName.eternal_engine_animal_5,
LocationName.eternal_engine_animal_6,
LocationName.eternal_engine_animal_7,
LocationName.eternal_engine_animal_8,
LocationName.eternal_engine_animal_9,
LocationName.eternal_engine_animal_10,
LocationName.eternal_engine_animal_11,
LocationName.eternal_engine_animal_12,
LocationName.eternal_engine_animal_13,
LocationName.eternal_engine_animal_14,
LocationName.eternal_engine_animal_15,
LocationName.eternal_engine_upgrade, LocationName.eternal_engine_upgrade,
] ]
eternal_engine_region = create_region(world, player, active_locations, LocationName.eternal_engine_region, eternal_engine_region = create_region(world, player, active_locations, LocationName.eternal_engine_region,
@ -421,6 +585,16 @@ def create_regions(world, player: int, active_locations):
LocationName.wild_canyon_omo_9, LocationName.wild_canyon_omo_9,
LocationName.wild_canyon_omo_10, LocationName.wild_canyon_omo_10,
LocationName.wild_canyon_beetle, LocationName.wild_canyon_beetle,
LocationName.wild_canyon_animal_1,
LocationName.wild_canyon_animal_2,
LocationName.wild_canyon_animal_3,
LocationName.wild_canyon_animal_4,
LocationName.wild_canyon_animal_5,
LocationName.wild_canyon_animal_6,
LocationName.wild_canyon_animal_7,
LocationName.wild_canyon_animal_8,
LocationName.wild_canyon_animal_9,
LocationName.wild_canyon_animal_10,
LocationName.wild_canyon_upgrade, LocationName.wild_canyon_upgrade,
] ]
wild_canyon_region = create_region(world, player, active_locations, LocationName.wild_canyon_region, wild_canyon_region = create_region(world, player, active_locations, LocationName.wild_canyon_region,
@ -448,6 +622,17 @@ def create_regions(world, player: int, active_locations):
LocationName.pumpkin_hill_omo_9, LocationName.pumpkin_hill_omo_9,
LocationName.pumpkin_hill_omo_10, LocationName.pumpkin_hill_omo_10,
LocationName.pumpkin_hill_omo_11, LocationName.pumpkin_hill_omo_11,
LocationName.pumpkin_hill_animal_1,
LocationName.pumpkin_hill_animal_2,
LocationName.pumpkin_hill_animal_3,
LocationName.pumpkin_hill_animal_4,
LocationName.pumpkin_hill_animal_5,
LocationName.pumpkin_hill_animal_6,
LocationName.pumpkin_hill_animal_7,
LocationName.pumpkin_hill_animal_8,
LocationName.pumpkin_hill_animal_9,
LocationName.pumpkin_hill_animal_10,
LocationName.pumpkin_hill_animal_11,
LocationName.pumpkin_hill_upgrade, LocationName.pumpkin_hill_upgrade,
] ]
pumpkin_hill_region = create_region(world, player, active_locations, LocationName.pumpkin_hill_region, pumpkin_hill_region = create_region(world, player, active_locations, LocationName.pumpkin_hill_region,
@ -473,6 +658,16 @@ def create_regions(world, player: int, active_locations):
LocationName.aquatic_mine_omo_6, LocationName.aquatic_mine_omo_6,
LocationName.aquatic_mine_omo_7, LocationName.aquatic_mine_omo_7,
LocationName.aquatic_mine_beetle, LocationName.aquatic_mine_beetle,
LocationName.aquatic_mine_animal_1,
LocationName.aquatic_mine_animal_2,
LocationName.aquatic_mine_animal_3,
LocationName.aquatic_mine_animal_4,
LocationName.aquatic_mine_animal_5,
LocationName.aquatic_mine_animal_6,
LocationName.aquatic_mine_animal_7,
LocationName.aquatic_mine_animal_8,
LocationName.aquatic_mine_animal_9,
LocationName.aquatic_mine_animal_10,
LocationName.aquatic_mine_upgrade, LocationName.aquatic_mine_upgrade,
] ]
aquatic_mine_region = create_region(world, player, active_locations, LocationName.aquatic_mine_region, aquatic_mine_region = create_region(world, player, active_locations, LocationName.aquatic_mine_region,
@ -502,6 +697,16 @@ def create_regions(world, player: int, active_locations):
LocationName.death_chamber_omo_8, LocationName.death_chamber_omo_8,
LocationName.death_chamber_omo_9, LocationName.death_chamber_omo_9,
LocationName.death_chamber_beetle, LocationName.death_chamber_beetle,
LocationName.death_chamber_animal_1,
LocationName.death_chamber_animal_2,
LocationName.death_chamber_animal_3,
LocationName.death_chamber_animal_4,
LocationName.death_chamber_animal_5,
LocationName.death_chamber_animal_6,
LocationName.death_chamber_animal_7,
LocationName.death_chamber_animal_8,
LocationName.death_chamber_animal_9,
LocationName.death_chamber_animal_10,
LocationName.death_chamber_upgrade, LocationName.death_chamber_upgrade,
] ]
death_chamber_region = create_region(world, player, active_locations, LocationName.death_chamber_region, death_chamber_region = create_region(world, player, active_locations, LocationName.death_chamber_region,
@ -523,6 +728,17 @@ def create_regions(world, player: int, active_locations):
LocationName.meteor_herd_omo_2, LocationName.meteor_herd_omo_2,
LocationName.meteor_herd_omo_3, LocationName.meteor_herd_omo_3,
LocationName.meteor_herd_beetle, LocationName.meteor_herd_beetle,
LocationName.meteor_herd_animal_1,
LocationName.meteor_herd_animal_2,
LocationName.meteor_herd_animal_3,
LocationName.meteor_herd_animal_4,
LocationName.meteor_herd_animal_5,
LocationName.meteor_herd_animal_6,
LocationName.meteor_herd_animal_7,
LocationName.meteor_herd_animal_8,
LocationName.meteor_herd_animal_9,
LocationName.meteor_herd_animal_10,
LocationName.meteor_herd_animal_11,
LocationName.meteor_herd_upgrade, LocationName.meteor_herd_upgrade,
] ]
meteor_herd_region = create_region(world, player, active_locations, LocationName.meteor_herd_region, meteor_herd_region = create_region(world, player, active_locations, LocationName.meteor_herd_region,
@ -552,6 +768,26 @@ def create_regions(world, player: int, active_locations):
LocationName.radical_highway_omo_7, LocationName.radical_highway_omo_7,
LocationName.radical_highway_omo_8, LocationName.radical_highway_omo_8,
LocationName.radical_highway_beetle, LocationName.radical_highway_beetle,
LocationName.radical_highway_animal_1,
LocationName.radical_highway_animal_2,
LocationName.radical_highway_animal_3,
LocationName.radical_highway_animal_4,
LocationName.radical_highway_animal_5,
LocationName.radical_highway_animal_6,
LocationName.radical_highway_animal_7,
LocationName.radical_highway_animal_8,
LocationName.radical_highway_animal_9,
LocationName.radical_highway_animal_10,
LocationName.radical_highway_animal_11,
LocationName.radical_highway_animal_12,
LocationName.radical_highway_animal_13,
LocationName.radical_highway_animal_14,
LocationName.radical_highway_animal_15,
LocationName.radical_highway_animal_16,
LocationName.radical_highway_animal_17,
LocationName.radical_highway_animal_18,
LocationName.radical_highway_animal_19,
LocationName.radical_highway_animal_20,
LocationName.radical_highway_upgrade, LocationName.radical_highway_upgrade,
] ]
radical_highway_region = create_region(world, player, active_locations, LocationName.radical_highway_region, radical_highway_region = create_region(world, player, active_locations, LocationName.radical_highway_region,
@ -579,6 +815,22 @@ def create_regions(world, player: int, active_locations):
LocationName.white_jungle_omo_4, LocationName.white_jungle_omo_4,
LocationName.white_jungle_omo_5, LocationName.white_jungle_omo_5,
LocationName.white_jungle_beetle, LocationName.white_jungle_beetle,
LocationName.white_jungle_animal_1,
LocationName.white_jungle_animal_2,
LocationName.white_jungle_animal_3,
LocationName.white_jungle_animal_4,
LocationName.white_jungle_animal_5,
LocationName.white_jungle_animal_6,
LocationName.white_jungle_animal_7,
LocationName.white_jungle_animal_8,
LocationName.white_jungle_animal_9,
LocationName.white_jungle_animal_10,
LocationName.white_jungle_animal_11,
LocationName.white_jungle_animal_12,
LocationName.white_jungle_animal_13,
LocationName.white_jungle_animal_14,
LocationName.white_jungle_animal_15,
LocationName.white_jungle_animal_16,
LocationName.white_jungle_upgrade, LocationName.white_jungle_upgrade,
] ]
white_jungle_region = create_region(world, player, active_locations, LocationName.white_jungle_region, white_jungle_region = create_region(world, player, active_locations, LocationName.white_jungle_region,
@ -600,6 +852,26 @@ def create_regions(world, player: int, active_locations):
LocationName.sky_rail_pipe_5, LocationName.sky_rail_pipe_5,
LocationName.sky_rail_pipe_6, LocationName.sky_rail_pipe_6,
LocationName.sky_rail_beetle, LocationName.sky_rail_beetle,
LocationName.sky_rail_animal_1,
LocationName.sky_rail_animal_2,
LocationName.sky_rail_animal_3,
LocationName.sky_rail_animal_4,
LocationName.sky_rail_animal_5,
LocationName.sky_rail_animal_6,
LocationName.sky_rail_animal_7,
LocationName.sky_rail_animal_8,
LocationName.sky_rail_animal_9,
LocationName.sky_rail_animal_10,
LocationName.sky_rail_animal_11,
LocationName.sky_rail_animal_12,
LocationName.sky_rail_animal_13,
LocationName.sky_rail_animal_14,
LocationName.sky_rail_animal_15,
LocationName.sky_rail_animal_16,
LocationName.sky_rail_animal_17,
LocationName.sky_rail_animal_18,
LocationName.sky_rail_animal_19,
LocationName.sky_rail_animal_20,
LocationName.sky_rail_upgrade, LocationName.sky_rail_upgrade,
] ]
sky_rail_region = create_region(world, player, active_locations, LocationName.sky_rail_region, sky_rail_region = create_region(world, player, active_locations, LocationName.sky_rail_region,
@ -619,6 +891,23 @@ def create_regions(world, player: int, active_locations):
LocationName.final_chase_pipe_3, LocationName.final_chase_pipe_3,
LocationName.final_chase_omo_1, LocationName.final_chase_omo_1,
LocationName.final_chase_beetle, LocationName.final_chase_beetle,
LocationName.final_chase_animal_1,
LocationName.final_chase_animal_2,
LocationName.final_chase_animal_3,
LocationName.final_chase_animal_4,
LocationName.final_chase_animal_5,
LocationName.final_chase_animal_6,
LocationName.final_chase_animal_7,
LocationName.final_chase_animal_8,
LocationName.final_chase_animal_9,
LocationName.final_chase_animal_10,
LocationName.final_chase_animal_11,
LocationName.final_chase_animal_12,
LocationName.final_chase_animal_13,
LocationName.final_chase_animal_14,
LocationName.final_chase_animal_15,
LocationName.final_chase_animal_16,
LocationName.final_chase_animal_17,
LocationName.final_chase_upgrade, LocationName.final_chase_upgrade,
] ]
final_chase_region = create_region(world, player, active_locations, LocationName.final_chase_region, final_chase_region = create_region(world, player, active_locations, LocationName.final_chase_region,
@ -645,6 +934,21 @@ def create_regions(world, player: int, active_locations):
LocationName.iron_gate_omo_5, LocationName.iron_gate_omo_5,
LocationName.iron_gate_omo_6, LocationName.iron_gate_omo_6,
LocationName.iron_gate_beetle, LocationName.iron_gate_beetle,
LocationName.iron_gate_animal_1,
LocationName.iron_gate_animal_2,
LocationName.iron_gate_animal_3,
LocationName.iron_gate_animal_4,
LocationName.iron_gate_animal_5,
LocationName.iron_gate_animal_6,
LocationName.iron_gate_animal_7,
LocationName.iron_gate_animal_8,
LocationName.iron_gate_animal_9,
LocationName.iron_gate_animal_10,
LocationName.iron_gate_animal_11,
LocationName.iron_gate_animal_12,
LocationName.iron_gate_animal_13,
LocationName.iron_gate_animal_14,
LocationName.iron_gate_animal_15,
LocationName.iron_gate_upgrade, LocationName.iron_gate_upgrade,
] ]
iron_gate_region = create_region(world, player, active_locations, LocationName.iron_gate_region, iron_gate_region = create_region(world, player, active_locations, LocationName.iron_gate_region,
@ -667,6 +971,21 @@ def create_regions(world, player: int, active_locations):
LocationName.sand_ocean_omo_1, LocationName.sand_ocean_omo_1,
LocationName.sand_ocean_omo_2, LocationName.sand_ocean_omo_2,
LocationName.sand_ocean_beetle, LocationName.sand_ocean_beetle,
LocationName.sand_ocean_animal_1,
LocationName.sand_ocean_animal_2,
LocationName.sand_ocean_animal_3,
LocationName.sand_ocean_animal_4,
LocationName.sand_ocean_animal_5,
LocationName.sand_ocean_animal_6,
LocationName.sand_ocean_animal_7,
LocationName.sand_ocean_animal_8,
LocationName.sand_ocean_animal_9,
LocationName.sand_ocean_animal_10,
LocationName.sand_ocean_animal_11,
LocationName.sand_ocean_animal_12,
LocationName.sand_ocean_animal_13,
LocationName.sand_ocean_animal_14,
LocationName.sand_ocean_animal_15,
LocationName.sand_ocean_upgrade, LocationName.sand_ocean_upgrade,
] ]
sand_ocean_region = create_region(world, player, active_locations, LocationName.sand_ocean_region, sand_ocean_region = create_region(world, player, active_locations, LocationName.sand_ocean_region,
@ -693,6 +1012,20 @@ def create_regions(world, player: int, active_locations):
LocationName.lost_colony_omo_7, LocationName.lost_colony_omo_7,
LocationName.lost_colony_omo_8, LocationName.lost_colony_omo_8,
LocationName.lost_colony_beetle, LocationName.lost_colony_beetle,
LocationName.lost_colony_animal_1,
LocationName.lost_colony_animal_2,
LocationName.lost_colony_animal_3,
LocationName.lost_colony_animal_4,
LocationName.lost_colony_animal_5,
LocationName.lost_colony_animal_6,
LocationName.lost_colony_animal_7,
LocationName.lost_colony_animal_8,
LocationName.lost_colony_animal_9,
LocationName.lost_colony_animal_10,
LocationName.lost_colony_animal_11,
LocationName.lost_colony_animal_12,
LocationName.lost_colony_animal_13,
LocationName.lost_colony_animal_14,
LocationName.lost_colony_upgrade, LocationName.lost_colony_upgrade,
] ]
lost_colony_region = create_region(world, player, active_locations, LocationName.lost_colony_region, lost_colony_region = create_region(world, player, active_locations, LocationName.lost_colony_region,
@ -715,6 +1048,21 @@ def create_regions(world, player: int, active_locations):
LocationName.weapons_bed_omo_1, LocationName.weapons_bed_omo_1,
LocationName.weapons_bed_omo_2, LocationName.weapons_bed_omo_2,
LocationName.weapons_bed_omo_3, LocationName.weapons_bed_omo_3,
LocationName.weapons_bed_animal_1,
LocationName.weapons_bed_animal_2,
LocationName.weapons_bed_animal_3,
LocationName.weapons_bed_animal_4,
LocationName.weapons_bed_animal_5,
LocationName.weapons_bed_animal_6,
LocationName.weapons_bed_animal_7,
LocationName.weapons_bed_animal_8,
LocationName.weapons_bed_animal_9,
LocationName.weapons_bed_animal_10,
LocationName.weapons_bed_animal_11,
LocationName.weapons_bed_animal_12,
LocationName.weapons_bed_animal_13,
LocationName.weapons_bed_animal_14,
LocationName.weapons_bed_animal_15,
LocationName.weapons_bed_upgrade, LocationName.weapons_bed_upgrade,
] ]
weapons_bed_region = create_region(world, player, active_locations, LocationName.weapons_bed_region, weapons_bed_region = create_region(world, player, active_locations, LocationName.weapons_bed_region,
@ -736,6 +1084,21 @@ def create_regions(world, player: int, active_locations):
LocationName.cosmic_wall_pipe_5, LocationName.cosmic_wall_pipe_5,
LocationName.cosmic_wall_omo_1, LocationName.cosmic_wall_omo_1,
LocationName.cosmic_wall_beetle, LocationName.cosmic_wall_beetle,
LocationName.cosmic_wall_animal_1,
LocationName.cosmic_wall_animal_2,
LocationName.cosmic_wall_animal_3,
LocationName.cosmic_wall_animal_4,
LocationName.cosmic_wall_animal_5,
LocationName.cosmic_wall_animal_6,
LocationName.cosmic_wall_animal_7,
LocationName.cosmic_wall_animal_8,
LocationName.cosmic_wall_animal_9,
LocationName.cosmic_wall_animal_10,
LocationName.cosmic_wall_animal_11,
LocationName.cosmic_wall_animal_12,
LocationName.cosmic_wall_animal_13,
LocationName.cosmic_wall_animal_14,
LocationName.cosmic_wall_animal_15,
LocationName.cosmic_wall_upgrade, LocationName.cosmic_wall_upgrade,
] ]
cosmic_wall_region = create_region(world, player, active_locations, LocationName.cosmic_wall_region, cosmic_wall_region = create_region(world, player, active_locations, LocationName.cosmic_wall_region,
@ -765,6 +1128,16 @@ def create_regions(world, player: int, active_locations):
LocationName.dry_lagoon_omo_11, LocationName.dry_lagoon_omo_11,
LocationName.dry_lagoon_omo_12, LocationName.dry_lagoon_omo_12,
LocationName.dry_lagoon_beetle, LocationName.dry_lagoon_beetle,
LocationName.dry_lagoon_animal_1,
LocationName.dry_lagoon_animal_2,
LocationName.dry_lagoon_animal_3,
LocationName.dry_lagoon_animal_4,
LocationName.dry_lagoon_animal_5,
LocationName.dry_lagoon_animal_6,
LocationName.dry_lagoon_animal_7,
LocationName.dry_lagoon_animal_8,
LocationName.dry_lagoon_animal_9,
LocationName.dry_lagoon_animal_10,
LocationName.dry_lagoon_upgrade, LocationName.dry_lagoon_upgrade,
] ]
dry_lagoon_region = create_region(world, player, active_locations, LocationName.dry_lagoon_region, dry_lagoon_region = create_region(world, player, active_locations, LocationName.dry_lagoon_region,
@ -791,6 +1164,16 @@ def create_regions(world, player: int, active_locations):
LocationName.egg_quarters_omo_6, LocationName.egg_quarters_omo_6,
LocationName.egg_quarters_omo_7, LocationName.egg_quarters_omo_7,
LocationName.egg_quarters_beetle, LocationName.egg_quarters_beetle,
LocationName.egg_quarters_animal_1,
LocationName.egg_quarters_animal_2,
LocationName.egg_quarters_animal_3,
LocationName.egg_quarters_animal_4,
LocationName.egg_quarters_animal_5,
LocationName.egg_quarters_animal_6,
LocationName.egg_quarters_animal_7,
LocationName.egg_quarters_animal_8,
LocationName.egg_quarters_animal_9,
LocationName.egg_quarters_animal_10,
LocationName.egg_quarters_upgrade, LocationName.egg_quarters_upgrade,
] ]
egg_quarters_region = create_region(world, player, active_locations, LocationName.egg_quarters_region, egg_quarters_region = create_region(world, player, active_locations, LocationName.egg_quarters_region,
@ -820,6 +1203,14 @@ def create_regions(world, player: int, active_locations):
LocationName.security_hall_omo_11, LocationName.security_hall_omo_11,
LocationName.security_hall_omo_12, LocationName.security_hall_omo_12,
LocationName.security_hall_beetle, LocationName.security_hall_beetle,
LocationName.security_hall_animal_1,
LocationName.security_hall_animal_2,
LocationName.security_hall_animal_3,
LocationName.security_hall_animal_4,
LocationName.security_hall_animal_5,
LocationName.security_hall_animal_6,
LocationName.security_hall_animal_7,
LocationName.security_hall_animal_8,
LocationName.security_hall_upgrade, LocationName.security_hall_upgrade,
] ]
security_hall_region = create_region(world, player, active_locations, LocationName.security_hall_region, security_hall_region = create_region(world, player, active_locations, LocationName.security_hall_region,
@ -854,6 +1245,16 @@ def create_regions(world, player: int, active_locations):
LocationName.mad_space_omo_4, LocationName.mad_space_omo_4,
LocationName.mad_space_omo_5, LocationName.mad_space_omo_5,
LocationName.mad_space_beetle, LocationName.mad_space_beetle,
LocationName.mad_space_animal_1,
LocationName.mad_space_animal_2,
LocationName.mad_space_animal_3,
LocationName.mad_space_animal_4,
LocationName.mad_space_animal_5,
LocationName.mad_space_animal_6,
LocationName.mad_space_animal_7,
LocationName.mad_space_animal_8,
LocationName.mad_space_animal_9,
LocationName.mad_space_animal_10,
LocationName.mad_space_upgrade, LocationName.mad_space_upgrade,
] ]
mad_space_region = create_region(world, player, active_locations, LocationName.mad_space_region, mad_space_region = create_region(world, player, active_locations, LocationName.mad_space_region,
@ -883,6 +1284,25 @@ def create_regions(world, player: int, active_locations):
LocationName.cannon_core_omo_7, LocationName.cannon_core_omo_7,
LocationName.cannon_core_omo_8, LocationName.cannon_core_omo_8,
LocationName.cannon_core_omo_9, LocationName.cannon_core_omo_9,
LocationName.cannon_core_animal_1,
LocationName.cannon_core_animal_2,
LocationName.cannon_core_animal_3,
LocationName.cannon_core_animal_4,
LocationName.cannon_core_animal_5,
LocationName.cannon_core_animal_6,
LocationName.cannon_core_animal_7,
LocationName.cannon_core_animal_8,
LocationName.cannon_core_animal_9,
LocationName.cannon_core_animal_10,
LocationName.cannon_core_animal_11,
LocationName.cannon_core_animal_12,
LocationName.cannon_core_animal_13,
LocationName.cannon_core_animal_14,
LocationName.cannon_core_animal_15,
LocationName.cannon_core_animal_16,
LocationName.cannon_core_animal_17,
LocationName.cannon_core_animal_18,
LocationName.cannon_core_animal_19,
LocationName.cannon_core_beetle, LocationName.cannon_core_beetle,
] ]
cannon_core_region = create_region(world, player, active_locations, LocationName.cannon_core_region, cannon_core_region = create_region(world, player, active_locations, LocationName.cannon_core_region,
@ -1027,7 +1447,7 @@ def create_regions(world, player: int, active_locations):
grand_prix_region_locations) grand_prix_region_locations)
world.regions += [grand_prix_region] world.regions += [grand_prix_region]
if world.goal[player] == 0 or world.goal[player] == 2: if world.goal[player] in [0, 2, 4, 5, 6]:
biolizard_region_locations = [ biolizard_region_locations = [
LocationName.finalhazard, LocationName.finalhazard,
] ]
@ -1035,15 +1455,25 @@ def create_regions(world, player: int, active_locations):
biolizard_region_locations) biolizard_region_locations)
world.regions += [biolizard_region] world.regions += [biolizard_region]
if world.goal[player] == 1 or world.goal[player] == 2: if world.goal[player] in [1, 2]:
green_hill_region_locations = [ green_hill_region_locations = [
LocationName.green_hill, LocationName.green_hill,
LocationName.green_hill_chao_1, LocationName.green_hill_chao_1,
#LocationName.green_hill_animal_1,
] ]
green_hill_region = create_region(world, player, active_locations, LocationName.green_hill_region, green_hill_region = create_region(world, player, active_locations, LocationName.green_hill_region,
green_hill_region_locations) green_hill_region_locations)
world.regions += [green_hill_region] world.regions += [green_hill_region]
if world.goal[player] in [4, 5, 6]:
for i in range(16):
boss_region_locations = [
"Boss Rush - " + str(i + 1),
]
boss_region = create_region(world, player, active_locations, "Boss Rush " + str(i + 1),
boss_region_locations)
world.regions += [boss_region]
# Set up the regions correctly. # Set up the regions correctly.
world.regions += [ world.regions += [
@ -1089,7 +1519,7 @@ def create_regions(world, player: int, active_locations):
] ]
def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_emblems, gate_bosses, first_cannons_core_mission: str, final_cannons_core_mission: str): def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_emblems, gate_bosses, boss_rush_bosses, first_cannons_core_mission: str, final_cannons_core_mission: str):
names: typing.Dict[str, int] = {} names: typing.Dict[str, int] = {}
connect(world, player, names, 'Menu', LocationName.gate_0_region) connect(world, player, names, 'Menu', LocationName.gate_0_region)
@ -1104,7 +1534,7 @@ def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_em
connect(world, player, names, LocationName.cannon_core_region, LocationName.biolizard_region, connect(world, player, names, LocationName.cannon_core_region, LocationName.biolizard_region,
lambda state: (state.can_reach(required_mission_name, "Location", player))) lambda state: (state.can_reach(required_mission_name, "Location", player)))
elif world.goal[player] == 1 or world.goal[player] == 2: elif world.goal[player] in [1, 2]:
connect(world, player, names, 'Menu', LocationName.green_hill_region, connect(world, player, names, 'Menu', LocationName.green_hill_region,
lambda state: (state.has(ItemName.white_emerald, player) and lambda state: (state.has(ItemName.white_emerald, player) and
state.has(ItemName.red_emerald, player) and state.has(ItemName.red_emerald, player) and
@ -1117,6 +1547,35 @@ def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_em
connect(world, player, names, LocationName.green_hill_region, LocationName.biolizard_region) connect(world, player, names, LocationName.green_hill_region, LocationName.biolizard_region)
elif world.goal[player] == 3: elif world.goal[player] == 3:
connect(world, player, names, LocationName.kart_race_expert_region, LocationName.grand_prix_region) connect(world, player, names, LocationName.kart_race_expert_region, LocationName.grand_prix_region)
elif world.goal[player] in [4, 5, 6]:
if world.goal[player] == 4:
connect(world, player, names, LocationName.gate_0_region, LocationName.boss_rush_1_region)
elif world.goal[player] == 5:
required_mission_name = first_cannons_core_mission
if world.required_cannons_core_missions[player].value == 1:
required_mission_name = final_cannons_core_mission
connect(world, player, names, LocationName.cannon_core_region, LocationName.boss_rush_1_region,
lambda state: (state.can_reach(required_mission_name, "Location", player)))
elif world.goal[player] == 6:
connect(world, player, names, LocationName.gate_0_region, LocationName.boss_rush_1_region,
lambda state: (state.has(ItemName.white_emerald, player) and
state.has(ItemName.red_emerald, player) and
state.has(ItemName.cyan_emerald, player) and
state.has(ItemName.purple_emerald, player) and
state.has(ItemName.green_emerald, player) and
state.has(ItemName.yellow_emerald, player) and
state.has(ItemName.blue_emerald, player)))
for i in range(15):
if boss_rush_bosses[i] == all_gate_bosses_table[king_boom_boo]:
connect(world, player, names, "Boss Rush " + str(i + 1), "Boss Rush " + str(i + 2),
lambda state: (state.has(ItemName.knuckles_shovel_claws, player)))
else:
connect(world, player, names, "Boss Rush " + str(i + 1), "Boss Rush " + str(i + 2))
connect(world, player, names, LocationName.boss_rush_16_region, LocationName.biolizard_region)
for i in range(len(gates[0].gate_levels)): for i in range(len(gates[0].gate_levels)):
connect(world, player, names, LocationName.gate_0_region, shuffleable_regions[gates[0].gate_levels[i]]) connect(world, player, names, LocationName.gate_0_region, shuffleable_regions[gates[0].gate_levels[i]])

View File

@ -329,7 +329,8 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int):
lambda state: state.has(ItemName.eggman_jet_engine, player)) lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule_safe(world, LocationName.egg_quarters_5, player, add_rule_safe(world, LocationName.egg_quarters_5, player,
lambda state: state.has(ItemName.rouge_pick_nails, player) and lambda state: state.has(ItemName.rouge_pick_nails, player) and
state.has(ItemName.rouge_treasure_scope, player)) state.has(ItemName.rouge_treasure_scope, player) and
state.has(ItemName.rouge_iron_boots, player))
add_rule_safe(world, LocationName.lost_colony_5, player, add_rule_safe(world, LocationName.lost_colony_5, player,
lambda state: state.has(ItemName.eggman_jet_engine, player) and lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player)) state.has(ItemName.eggman_large_cannon, player))
@ -495,8 +496,6 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int):
lambda state: state.has(ItemName.tails_booster, player)) lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_pipe_1, player), add_rule(world.get_location(LocationName.hidden_base_pipe_1, player),
lambda state: state.has(ItemName.tails_booster, player)) lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.eternal_engine_pipe_1, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.sand_ocean_pipe_1, player), add_rule(world.get_location(LocationName.sand_ocean_pipe_1, player),
lambda state: state.has(ItemName.eggman_jet_engine, player)) lambda state: state.has(ItemName.eggman_jet_engine, player))
@ -827,6 +826,507 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int):
state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.knuckles_hammer_gloves, player) and
state.has(ItemName.knuckles_air_necklace, player)) state.has(ItemName.knuckles_air_necklace, player))
# Animal Upgrade Requirements
if world.animalsanity[player]:
add_rule(world.get_location(LocationName.hidden_base_animal_2, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_2, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.hidden_base_animal_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_3, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_3, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_3, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_4, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_4, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_4, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.mad_space_animal_4, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_4, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.mission_street_animal_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_5, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_5, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_5, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.mad_space_animal_5, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_5, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_5, player),
lambda state: state.has(ItemName.tails_booster, player) and
(state.has(ItemName.eggman_jet_engine, player) or
state.has(ItemName.eggman_large_cannon, player)))
add_rule(world.get_location(LocationName.metal_harbor_animal_6, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_animal_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_6, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.death_chamber_animal_6, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_6, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_6, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.mad_space_animal_6, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_6, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_6, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.metal_harbor_animal_7, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_animal_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_7, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.death_chamber_animal_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_animal_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_7, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_animal_7, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) or
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_7, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.security_hall_animal_7, player),
lambda state: state.has(ItemName.rouge_pick_nails, player) or
state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.mad_space_animal_7, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_7, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_7, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.metal_harbor_animal_8, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_animal_8, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_8, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_8, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.death_chamber_animal_8, 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_animal_8, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_8, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_animal_8, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_8, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.security_hall_animal_8, player),
lambda state: state.has(ItemName.rouge_pick_nails, player) and
state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.mad_space_animal_8, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_8, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_8, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.metal_harbor_animal_9, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_animal_9, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_9, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_9, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.death_chamber_animal_9, 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_animal_9, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_9, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.final_rush_animal_9, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_animal_9, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_9, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.mad_space_animal_9, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_9, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_9, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.wild_canyon_animal_10, player),
lambda state: state.has(ItemName.knuckles_shovel_claws, player))
add_rule(world.get_location(LocationName.metal_harbor_animal_10, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_animal_10, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.aquatic_mine_animal_10, player),
lambda state: state.has(ItemName.knuckles_mystic_melody, player))
add_rule(world.get_location(LocationName.hidden_base_animal_10, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_10, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.death_chamber_animal_10, 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_animal_10, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_10, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.final_rush_animal_10, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.egg_quarters_animal_10, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.lost_colony_animal_10, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_10, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.mad_space_animal_10, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_10, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_10, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.metal_harbor_animal_11, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_animal_11, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_11, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_11, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_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_animal_11, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and
(state.has(ItemName.sonic_flame_ring, player) or
state.has(ItemName.sonic_mystic_melody, player)))
add_rule(world.get_location(LocationName.final_rush_animal_11, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_animal_11, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_11, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.white_jungle_animal_11, player),
lambda state: state.has(ItemName.shadow_air_shoes, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_11, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_11, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.metal_harbor_animal_12, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_animal_12, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_12, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_12, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_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_animal_12, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and
state.has(ItemName.sonic_flame_ring, player) and
(state.has(ItemName.sonic_light_shoes, player) or
state.has(ItemName.sonic_mystic_melody, player)))
add_rule(world.get_location(LocationName.final_rush_animal_12, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.sand_ocean_animal_12, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.lost_colony_animal_12, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_12, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.white_jungle_animal_12, player),
lambda state: state.has(ItemName.shadow_air_shoes, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_12, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_12, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.prison_lane_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player) or
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.metal_harbor_animal_13, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_13, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_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))
add_rule(world.get_location(LocationName.final_rush_animal_13, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.sand_ocean_animal_13, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.lost_colony_animal_13, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_13, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.white_jungle_animal_13, player),
lambda state: state.has(ItemName.shadow_air_shoes, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_13, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player) and
(state.has(ItemName.knuckles_air_necklace, player) or
state.has(ItemName.knuckles_hammer_gloves, player)))
add_rule(world.get_location(LocationName.prison_lane_animal_14, player),
lambda state: state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.metal_harbor_animal_14, player),
lambda state: state.has(ItemName.sonic_light_shoes, player))
add_rule(world.get_location(LocationName.mission_street_animal_14, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_14, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_14, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_14, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_14, 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.final_rush_animal_14, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.sand_ocean_animal_14, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.lost_colony_animal_14, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_14, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.white_jungle_animal_14, player),
lambda state: state.has(ItemName.shadow_air_shoes, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_14, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_14, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_air_necklace, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.prison_lane_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.mission_street_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.hidden_base_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_15, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_15, 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.final_rush_animal_15, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.iron_gate_animal_15, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.sand_ocean_animal_15, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_15, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.white_jungle_animal_15, player),
lambda state: state.has(ItemName.shadow_air_shoes, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_15, player),
lambda state: state.has(ItemName.eggman_mystic_melody, player) and
state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_air_necklace, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.mission_street_animal_16, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_16, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and
(state.has(ItemName.sonic_flame_ring, player) or
(state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_mystic_melody, player))))
add_rule(world.get_location(LocationName.crazy_gadget_animal_16, 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) and
state.has(ItemName.sonic_mystic_melody, player))
add_rule(world.get_location(LocationName.final_rush_animal_16, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.white_jungle_animal_16, player),
lambda state: state.has(ItemName.shadow_flame_ring, player) and
state.has(ItemName.shadow_air_shoes, player))
add_rule(world.get_location(LocationName.cannon_core_animal_16, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_air_necklace, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_17, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_bounce_bracelet, player) and
state.has(ItemName.sonic_mystic_melody, player))
add_rule(world.get_location(LocationName.final_chase_animal_17, player),
lambda state: state.has(ItemName.shadow_flame_ring, player))
add_rule(world.get_location(LocationName.cannon_core_animal_17, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_air_necklace, player) and
state.has(ItemName.knuckles_hammer_gloves, player) and
(state.has(ItemName.sonic_bounce_bracelet, player) or
state.has(ItemName.sonic_flame_ring, player)))
add_rule(world.get_location(LocationName.pyramid_cave_animal_18, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_bounce_bracelet, player) and
state.has(ItemName.sonic_mystic_melody, player))
add_rule(world.get_location(LocationName.cannon_core_animal_18, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_air_necklace, player) and
state.has(ItemName.knuckles_hammer_gloves, player) and
state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_19, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_bounce_bracelet, player) and
state.has(ItemName.sonic_mystic_melody, player))
add_rule(world.get_location(LocationName.cannon_core_animal_19, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_air_necklace, player) and
state.has(ItemName.knuckles_hammer_gloves, player) and
state.has(ItemName.sonic_bounce_bracelet, player) and
state.has(ItemName.sonic_flame_ring, player))
add_rule(world.get_location(LocationName.radical_highway_animal_20, player),
lambda state: state.has(ItemName.shadow_flame_ring, player))
def set_mission_upgrade_rules_hard(world: MultiWorld, player: int): def set_mission_upgrade_rules_hard(world: MultiWorld, player: int):
# Mission 1 Upgrade Requirements # Mission 1 Upgrade Requirements
add_rule_safe(world, LocationName.pumpkin_hill_1, player, add_rule_safe(world, LocationName.pumpkin_hill_1, player,
@ -1123,8 +1623,6 @@ def set_mission_upgrade_rules_hard(world: MultiWorld, player: int):
if world.whistlesanity[player].value == 1 or world.whistlesanity[player].value == 3: if world.whistlesanity[player].value == 1 or world.whistlesanity[player].value == 3:
add_rule(world.get_location(LocationName.hidden_base_pipe_1, player), add_rule(world.get_location(LocationName.hidden_base_pipe_1, player),
lambda state: state.has(ItemName.tails_booster, player)) lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.eternal_engine_pipe_1, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.cosmic_wall_pipe_1, player), add_rule(world.get_location(LocationName.cosmic_wall_pipe_1, player),
lambda state: state.has(ItemName.eggman_jet_engine, player)) lambda state: state.has(ItemName.eggman_jet_engine, player))
@ -1359,6 +1857,338 @@ def set_mission_upgrade_rules_hard(world: MultiWorld, player: int):
lambda state: state.has(ItemName.tails_booster, player) and lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.knuckles_hammer_gloves, player)) state.has(ItemName.knuckles_hammer_gloves, player))
# Animal Upgrade Requirements
if world.animalsanity[player]:
add_rule(world.get_location(LocationName.hidden_base_animal_2, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_2, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.hidden_base_animal_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_3, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_3, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_3, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_4, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_4, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_4, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_4, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_5, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_5, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_5, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_5, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_6, player),
lambda state: state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_6, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_6, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_6, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_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_animal_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_7, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.security_hall_animal_7, player),
lambda state: state.has(ItemName.rouge_pick_nails, player) or
state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_7, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_7, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_8, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_8, 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_animal_8, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_8, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.security_hall_animal_8, player),
lambda state: state.has(ItemName.rouge_pick_nails, player) and
state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_8, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_8, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.mission_street_animal_9, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_9, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_9, 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_animal_9, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.final_rush_animal_9, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_9, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_9, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_9, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.wild_canyon_animal_10, player),
lambda state: state.has(ItemName.knuckles_shovel_claws, player))
add_rule(world.get_location(LocationName.mission_street_animal_10, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.aquatic_mine_animal_10, player),
lambda state: state.has(ItemName.knuckles_mystic_melody, player))
add_rule(world.get_location(LocationName.hidden_base_animal_10, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.death_chamber_animal_10, 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_animal_10, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.final_rush_animal_10, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.egg_quarters_animal_10, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.lost_colony_animal_10, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_10, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.mad_space_animal_10, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_10, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_10, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.mission_street_animal_11, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_11, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_11, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.final_rush_animal_11, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_animal_11, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_11, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_11, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_11, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.mission_street_animal_12, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_12, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_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_animal_12, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and
state.has(ItemName.sonic_flame_ring, player))
add_rule(world.get_location(LocationName.final_rush_animal_12, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_animal_12, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_12, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_12, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_12, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.prison_lane_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player) or
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.mission_street_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_13, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_flame_ring, player))
add_rule(world.get_location(LocationName.final_rush_animal_13, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_animal_13, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_13, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_13, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_13, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.prison_lane_animal_14, player),
lambda state: state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.mission_street_animal_14, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.hidden_base_animal_14, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_14, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_14, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_flame_ring, player))
add_rule(world.get_location(LocationName.final_rush_animal_14, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.lost_colony_animal_14, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_14, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_14, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_14, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.prison_lane_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.mission_street_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.hidden_base_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.eternal_engine_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_15, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_flame_ring, player))
add_rule(world.get_location(LocationName.final_rush_animal_15, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.iron_gate_animal_15, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.sand_ocean_animal_15, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.weapons_bed_animal_15, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
state.has(ItemName.eggman_large_cannon, player))
add_rule(world.get_location(LocationName.cosmic_wall_animal_15, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(world.get_location(LocationName.cannon_core_animal_15, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.mission_street_animal_16, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.tails_bazooka, player))
add_rule(world.get_location(LocationName.crazy_gadget_animal_16, player),
lambda state: state.has(ItemName.sonic_light_shoes, player) and
state.has(ItemName.sonic_flame_ring, player))
add_rule(world.get_location(LocationName.final_rush_animal_16, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(world.get_location(LocationName.cannon_core_animal_16, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.final_chase_animal_17, player),
lambda state: state.has(ItemName.shadow_flame_ring, player))
add_rule(world.get_location(LocationName.cannon_core_animal_17, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.cannon_core_animal_18, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
add_rule(world.get_location(LocationName.pyramid_cave_animal_19, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and
state.has(ItemName.sonic_mystic_melody, player))
add_rule(world.get_location(LocationName.cannon_core_animal_19, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.eggman_large_cannon, player) and
state.has(ItemName.knuckles_hammer_gloves, player) and
state.has(ItemName.sonic_flame_ring, player))
add_rule(world.get_location(LocationName.radical_highway_animal_20, player),
lambda state: state.has(ItemName.shadow_flame_ring, player))
def set_boss_gate_rules(world: MultiWorld, player: int, gate_bosses: typing.Dict[int, int]): def set_boss_gate_rules(world: MultiWorld, player: int, gate_bosses: typing.Dict[int, int]):
for x in range(len(gate_bosses)): for x in range(len(gate_bosses)):
@ -1367,7 +2197,7 @@ def set_boss_gate_rules(world: MultiWorld, player: int, gate_bosses: typing.Dict
lambda state: state.has(ItemName.knuckles_shovel_claws, player)) lambda state: state.has(ItemName.knuckles_shovel_claws, player))
def set_rules(world: MultiWorld, player: int, gate_bosses: typing.Dict[int, int], mission_map: typing.Dict[int, int], mission_count_map: typing.Dict[int, int]): def set_rules(world: MultiWorld, player: int, gate_bosses: typing.Dict[int, int], boss_rush_map: typing.Dict[int, int], mission_map: typing.Dict[int, int], mission_count_map: typing.Dict[int, int]):
# Mission Progression Rules (Mission 1 begets Mission 2, etc.) # Mission Progression Rules (Mission 1 begets Mission 2, etc.)
set_mission_progress_rules(world, player, mission_map, mission_count_map) set_mission_progress_rules(world, player, mission_map, mission_count_map)
@ -1378,6 +2208,12 @@ def set_rules(world: MultiWorld, player: int, gate_bosses: typing.Dict[int, int]
elif world.logic_difficulty[player].value == 1: elif world.logic_difficulty[player].value == 1:
set_mission_upgrade_rules_hard(world, player) set_mission_upgrade_rules_hard(world, player)
if world.goal[player] in [4, 5, 6]:
for i in range(16):
if boss_rush_map[i] == 10:
add_rule(world.get_location("Boss Rush - " + str(i + 1), player),
lambda state: (state.has(ItemName.knuckles_shovel_claws, player)))
# Upgrade Requirements for each boss gate # Upgrade Requirements for each boss gate
set_boss_gate_rules(world, player, gate_bosses) set_boss_gate_rules(world, player, gate_bosses)

View File

@ -10,7 +10,7 @@ from .Regions import create_regions, shuffleable_regions, connect_regions, Level
from .Rules import set_rules from .Rules import set_rules
from .Names import ItemName, LocationName from .Names import ItemName, LocationName
from worlds.AutoWorld import WebWorld, World from worlds.AutoWorld import WebWorld, World
from .GateBosses import get_gate_bosses, get_boss_name from .GateBosses import get_gate_bosses, get_boss_rush_bosses, get_boss_name
from .Missions import get_mission_table, get_mission_count_table, get_first_and_last_cannons_core_missions from .Missions import get_mission_table, get_mission_count_table, get_first_and_last_cannons_core_missions
import Patch import Patch
@ -52,7 +52,7 @@ class SA2BWorld(World):
game: str = "Sonic Adventure 2 Battle" game: str = "Sonic Adventure 2 Battle"
option_definitions = sa2b_options option_definitions = sa2b_options
topology_present = False topology_present = False
data_version = 5 data_version = 6
item_name_groups = item_groups item_name_groups = item_groups
item_name_to_id = {name: data.code for name, data in item_table.items()} item_name_to_id = {name: data.code for name, data in item_table.items()}
@ -61,30 +61,35 @@ class SA2BWorld(World):
location_table: typing.Dict[str, int] location_table: typing.Dict[str, int]
music_map: typing.Dict[int, int] music_map: typing.Dict[int, int]
voice_map: typing.Dict[int, int]
mission_map: typing.Dict[int, int] mission_map: typing.Dict[int, int]
mission_count_map: typing.Dict[int, int] mission_count_map: typing.Dict[int, int]
emblems_for_cannons_core: int emblems_for_cannons_core: int
region_emblem_map: typing.Dict[int, int] region_emblem_map: typing.Dict[int, int]
gate_costs: typing.Dict[int, int] gate_costs: typing.Dict[int, int]
gate_bosses: typing.Dict[int, int] gate_bosses: typing.Dict[int, int]
boss_rush_map: typing.Dict[int, int]
web = SA2BWeb() web = SA2BWeb()
def _get_slot_data(self): def _get_slot_data(self):
return { return {
"ModVersion": 201, "ModVersion": 202,
"Goal": self.multiworld.goal[self.player].value, "Goal": self.multiworld.goal[self.player].value,
"MusicMap": self.music_map, "MusicMap": self.music_map,
"VoiceMap": self.voice_map,
"MissionMap": self.mission_map, "MissionMap": self.mission_map,
"MissionCountMap": self.mission_count_map, "MissionCountMap": self.mission_count_map,
"MusicShuffle": self.multiworld.music_shuffle[self.player].value, "MusicShuffle": self.multiworld.music_shuffle[self.player].value,
"Narrator": self.multiworld.narrator[self.player].value, "Narrator": self.multiworld.narrator[self.player].value,
"MinigameTrapDifficulty": self.multiworld.minigame_trap_difficulty[self.player].value, "MinigameTrapDifficulty": self.multiworld.minigame_trap_difficulty[self.player].value,
"RingLoss": self.multiworld.ring_loss[self.player].value, "RingLoss": self.multiworld.ring_loss[self.player].value,
"RingLink": self.multiworld.ring_link[self.player].value,
"RequiredRank": self.multiworld.required_rank[self.player].value, "RequiredRank": self.multiworld.required_rank[self.player].value,
"ChaoKeys": self.multiworld.keysanity[self.player].value, "ChaoKeys": self.multiworld.keysanity[self.player].value,
"Whistlesanity": self.multiworld.whistlesanity[self.player].value, "Whistlesanity": self.multiworld.whistlesanity[self.player].value,
"GoldBeetles": self.multiworld.beetlesanity[self.player].value, "GoldBeetles": self.multiworld.beetlesanity[self.player].value,
"OmochaoChecks": self.multiworld.omosanity[self.player].value, "OmochaoChecks": self.multiworld.omosanity[self.player].value,
"AnimalChecks": self.multiworld.animalsanity[self.player].value,
"KartRaceChecks": self.multiworld.kart_race_checks[self.player].value, "KartRaceChecks": self.multiworld.kart_race_checks[self.player].value,
"ChaoRaceChecks": self.multiworld.chao_race_checks[self.player].value, "ChaoRaceChecks": self.multiworld.chao_race_checks[self.player].value,
"ChaoGardenDifficulty": self.multiworld.chao_garden_difficulty[self.player].value, "ChaoGardenDifficulty": self.multiworld.chao_garden_difficulty[self.player].value,
@ -97,6 +102,7 @@ class SA2BWorld(World):
"RegionEmblemMap": self.region_emblem_map, "RegionEmblemMap": self.region_emblem_map,
"GateCosts": self.gate_costs, "GateCosts": self.gate_costs,
"GateBosses": self.gate_bosses, "GateBosses": self.gate_bosses,
"BossRushMap": self.boss_rush_map,
} }
def _create_items(self, name: str): def _create_items(self, name: str):
@ -160,19 +166,26 @@ class SA2BWorld(World):
self.multiworld.confusion_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.tiny_trap_weight[self.player].value = 0
self.multiworld.gravity_trap_weight[self.player].value = 0 self.multiworld.gravity_trap_weight[self.player].value = 0
self.multiworld.ice_trap_weight[self.player].value = 0
self.multiworld.slow_trap_weight[self.player].value = 0
valid_trap_weights = self.multiworld.exposition_trap_weight[self.player].value + self.multiworld.pong_trap_weight[self.player].value valid_trap_weights = self.multiworld.exposition_trap_weight[self.player].value + \
self.multiworld.cutscene_trap_weight[self.player].value + \
self.multiworld.pong_trap_weight[self.player].value
if valid_trap_weights == 0: if valid_trap_weights == 0:
self.multiworld.exposition_trap_weight[self.player].value = 4 self.multiworld.exposition_trap_weight[self.player].value = 4
self.multiworld.cutscene_trap_weight[self.player].value = 4
self.multiworld.pong_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: if self.multiworld.kart_race_checks[self.player].value == 0:
self.multiworld.kart_race_checks[self.player].value = 2 self.multiworld.kart_race_checks[self.player].value = 2
self.gate_bosses = {} self.gate_bosses = {}
self.boss_rush_map = {}
else: else:
self.gate_bosses = get_gate_bosses(self.multiworld, self.player) self.gate_bosses = get_gate_bosses(self.multiworld, self.player)
self.boss_rush_map = get_boss_rush_bosses(self.multiworld, self.player)
def create_regions(self): def create_regions(self):
self.mission_map = get_mission_table(self.multiworld, self.player) self.mission_map = get_mission_table(self.multiworld, self.player)
@ -182,7 +195,7 @@ class SA2BWorld(World):
create_regions(self.multiworld, self.player, self.location_table) create_regions(self.multiworld, self.player, self.location_table)
# Not Generate Basic # Not Generate Basic
if self.multiworld.goal[self.player].value == 0 or self.multiworld.goal[self.player].value == 2: if self.multiworld.goal[self.player].value in [0, 2, 4, 5, 6]:
self.multiworld.get_location(LocationName.finalhazard, self.player).place_locked_item(self.create_item(ItemName.maria)) self.multiworld.get_location(LocationName.finalhazard, self.player).place_locked_item(self.create_item(ItemName.maria))
elif self.multiworld.goal[self.player].value == 1: 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)) self.multiworld.get_location(LocationName.green_hill, self.player).place_locked_item(self.create_item(ItemName.maria))
@ -198,16 +211,16 @@ class SA2BWorld(World):
if self.multiworld.goal[self.player].value != 3: if self.multiworld.goal[self.player].value != 3:
# Fill item pool with all required items # Fill item pool with all required items
for item in {**upgrades_table}: for item in {**upgrades_table}:
itempool += self._create_items(item) itempool += [self.create_item(item, False, self.multiworld.goal[self.player].value)]
if self.multiworld.goal[self.player].value == 1 or self.multiworld.goal[self.player].value == 2: if self.multiworld.goal[self.player].value in [1, 2, 6]:
# Some flavor of Chaos Emerald Hunt # Some flavor of Chaos Emerald Hunt
for item in {**emeralds_table}: for item in {**emeralds_table}:
itempool += self._create_items(item) itempool += self._create_items(item)
# Cap at 250 Emblems # Cap at player-specified Emblem count
raw_emblem_count = total_required_locations - len(itempool) raw_emblem_count = total_required_locations - len(itempool)
total_emblem_count = min(raw_emblem_count, 250) total_emblem_count = min(raw_emblem_count, self.multiworld.max_emblem_cap[self.player].value)
extra_junk_count = raw_emblem_count - total_emblem_count extra_junk_count = raw_emblem_count - total_emblem_count
self.emblems_for_cannons_core = math.floor( self.emblems_for_cannons_core = math.floor(
@ -253,7 +266,7 @@ class SA2BWorld(World):
first_cannons_core_mission, final_cannons_core_mission = get_first_and_last_cannons_core_missions(self.mission_map, self.mission_count_map) first_cannons_core_mission, final_cannons_core_mission = get_first_and_last_cannons_core_missions(self.mission_map, self.mission_count_map)
connect_regions(self.multiworld, self.player, gates, self.emblems_for_cannons_core, self.gate_bosses, first_cannons_core_mission, final_cannons_core_mission) connect_regions(self.multiworld, self.player, gates, self.emblems_for_cannons_core, self.gate_bosses, self.boss_rush_map, first_cannons_core_mission, final_cannons_core_mission)
max_required_emblems = max(max(emblem_requirement_list), self.emblems_for_cannons_core) max_required_emblems = max(max(emblem_requirement_list), self.emblems_for_cannons_core)
itempool += [self.create_item(ItemName.emblem) for _ in range(max_required_emblems)] itempool += [self.create_item(ItemName.emblem) for _ in range(max_required_emblems)]
@ -271,6 +284,9 @@ class SA2BWorld(World):
trap_weights += ([ItemName.gravity_trap] * self.multiworld.gravity_trap_weight[self.player].value) trap_weights += ([ItemName.gravity_trap] * self.multiworld.gravity_trap_weight[self.player].value)
trap_weights += ([ItemName.exposition_trap] * self.multiworld.exposition_trap_weight[self.player].value) trap_weights += ([ItemName.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.darkness_trap] * self.multiworld.darkness_trap_weight[self.player].value)
trap_weights += ([ItemName.ice_trap] * self.multiworld.ice_trap_weight[self.player].value)
trap_weights += ([ItemName.slow_trap] * self.multiworld.slow_trap_weight[self.player].value)
trap_weights += ([ItemName.cutscene_trap] * self.multiworld.cutscene_trap_weight[self.player].value)
trap_weights += ([ItemName.pong_trap] * self.multiworld.pong_trap_weight[self.player].value) trap_weights += ([ItemName.pong_trap] * self.multiworld.pong_trap_weight[self.player].value)
junk_count += extra_junk_count junk_count += extra_junk_count
@ -347,12 +363,52 @@ class SA2BWorld(World):
self.music_map = dict(zip(musiclist_o, musiclist_s)) self.music_map = dict(zip(musiclist_o, musiclist_s))
def create_item(self, name: str, force_non_progression=False) -> Item: # Voice Shuffle
if self.multiworld.voice_shuffle[self.player] == "shuffled":
voicelist_o = list(range(0, 2623))
voicelist_s = voicelist_o.copy()
self.multiworld.random.shuffle(voicelist_s)
self.voice_map = dict(zip(voicelist_o, voicelist_s))
elif self.multiworld.voice_shuffle[self.player] == "rude":
voicelist_o = list(range(0, 2623))
voicelist_s = voicelist_o.copy()
self.multiworld.random.shuffle(voicelist_s)
for i in range(len(voicelist_s)):
if self.multiworld.random.randint(1,100) > 80:
voicelist_s[i] = 17
self.voice_map = dict(zip(voicelist_o, voicelist_s))
elif self.multiworld.voice_shuffle[self.player] == "chao":
voicelist_o = list(range(0, 2623))
voicelist_s = voicelist_o.copy()
self.multiworld.random.shuffle(voicelist_s)
for i in range(len(voicelist_s)):
voicelist_s[i] = self.multiworld.random.choice(range(2586, 2608))
self.voice_map = dict(zip(voicelist_o, voicelist_s))
elif self.multiworld.voice_shuffle[self.player] == "singularity":
voicelist_o = list(range(0, 2623))
voicelist_s = [self.multiworld.random.choice(voicelist_o)] * len(voicelist_o)
self.voice_map = dict(zip(voicelist_o, voicelist_s))
else:
voicelist_o = list(range(0, 2623))
voicelist_s = voicelist_o.copy()
self.voice_map = dict(zip(voicelist_o, voicelist_s))
def create_item(self, name: str, force_non_progression=False, goal=0) -> Item:
data = item_table[name] data = item_table[name]
if force_non_progression: if force_non_progression:
classification = ItemClassification.filler classification = ItemClassification.filler
elif name == ItemName.emblem: elif name == ItemName.emblem or \
name in emeralds_table.keys() or \
(name == ItemName.knuckles_shovel_claws and goal in [4, 5]):
classification = ItemClassification.progression_skip_balancing classification = ItemClassification.progression_skip_balancing
elif data.progression: elif data.progression:
classification = ItemClassification.progression classification = ItemClassification.progression
@ -369,18 +425,28 @@ class SA2BWorld(World):
self.multiworld.random.choice(junk_table.keys()) self.multiworld.random.choice(junk_table.keys())
def set_rules(self): def set_rules(self):
set_rules(self.multiworld, self.player, self.gate_bosses, self.mission_map, self.mission_count_map) set_rules(self.multiworld, self.player, self.gate_bosses, self.boss_rush_map, self.mission_map, self.mission_count_map)
def write_spoiler(self, spoiler_handle: typing.TextIO): def write_spoiler(self, spoiler_handle: typing.TextIO):
if self.multiworld.number_of_level_gates[self.player].value > 0: if self.multiworld.number_of_level_gates[self.player].value > 0 or self.multiworld.goal[self.player].value in [4, 5, 6]:
spoiler_handle.write("\n") spoiler_handle.write("\n")
header_text = "Sonic Adventure 2 Bosses for {}:\n" header_text = "Sonic Adventure 2 Bosses for {}:\n"
header_text = header_text.format(self.multiworld.player_name[self.player]) header_text = header_text.format(self.multiworld.player_name[self.player])
spoiler_handle.write(header_text) spoiler_handle.write(header_text)
for x in range(len(self.gate_bosses.values())):
text = "Gate {0} Boss: {1}\n" if self.multiworld.number_of_level_gates[self.player].value > 0:
text = text.format((x + 1), get_boss_name(self.gate_bosses[x + 1])) for x in range(len(self.gate_bosses.values())):
spoiler_handle.writelines(text) text = "Gate {0} Boss: {1}\n"
text = text.format((x + 1), get_boss_name(self.gate_bosses[x + 1]))
spoiler_handle.writelines(text)
spoiler_handle.write("\n")
if self.multiworld.goal[self.player].value in [4, 5, 6]:
for x in range(len(self.boss_rush_map.values())):
text = "Boss Rush Boss {0}: {1}\n"
text = text.format((x + 1), get_boss_name(self.boss_rush_map[x]))
spoiler_handle.writelines(text)
spoiler_handle.write("\n")
def extend_hint_information(self, hint_data: typing.Dict[int, typing.Dict[int, str]]): def extend_hint_information(self, hint_data: typing.Dict[int, typing.Dict[int, str]]):
gate_names = [ gate_names = [