diff --git a/worlds/sa2b/AestheticData.py b/worlds/sa2b/AestheticData.py new file mode 100644 index 00000000..f3699e81 --- /dev/null +++ b/worlds/sa2b/AestheticData.py @@ -0,0 +1,342 @@ + +chao_name_conversion = { + "!": 0x01, + "!": 0x02, + "#": 0x03, + "$": 0x04, + "%": 0x05, + "&": 0x06, + "\\": 0x07, + "(": 0x08, + ")": 0x09, + "*": 0x0A, + "+": 0x0B, + ",": 0x0C, + "-": 0x0D, + ".": 0x0E, + "/": 0x0F, + + "0": 0x10, + "1": 0x11, + "2": 0x12, + "3": 0x13, + "4": 0x14, + "5": 0x15, + "6": 0x16, + "7": 0x17, + "8": 0x18, + "9": 0x19, + ":": 0x1A, + ";": 0x1B, + "<": 0x1C, + "=": 0x1D, + ">": 0x1E, + "?": 0x1F, + + "@": 0x20, + "A": 0x21, + "B": 0x22, + "C": 0x23, + "D": 0x24, + "E": 0x25, + "F": 0x26, + "G": 0x27, + "H": 0x28, + "I": 0x29, + "J": 0x2A, + "K": 0x2B, + "L": 0x2C, + "M": 0x2D, + "N": 0x2E, + "O": 0x2F, + + "P": 0x30, + "Q": 0x31, + "R": 0x32, + "S": 0x33, + "T": 0x34, + "U": 0x35, + "V": 0x36, + "W": 0x37, + "X": 0x38, + "Y": 0x39, + "Z": 0x3A, + "[": 0x3B, + "¥": 0x3C, + "]": 0x3D, + "^": 0x3E, + "_": 0x3F, + + "`": 0x40, + "a": 0x41, + "b": 0x42, + "c": 0x43, + "d": 0x44, + "e": 0x45, + "f": 0x46, + "g": 0x47, + "h": 0x48, + "i": 0x49, + "j": 0x4A, + "k": 0x4B, + "l": 0x4C, + "m": 0x4D, + "n": 0x4E, + "o": 0x4F, + + "p": 0x50, + "q": 0x51, + "r": 0x52, + "s": 0x53, + "t": 0x54, + "u": 0x55, + "v": 0x56, + "w": 0x57, + "x": 0x58, + "y": 0x59, + "z": 0x5A, + "{": 0x5B, + "|": 0x5C, + "}": 0x5D, + "~": 0x5E, + " ": 0x5F, +} + +sample_chao_names = [ + "Aginah", + "Biter", + "Steve", + "Ryley", + "Watcher", + "Acrid", + "Sheik", + "Lunais", + "Samus", + "The Kid", + "Jack", + "Sir Lee", + "Viridian", + "Rouhi", + "Toad", + "Merit", + "Ridley", + "Hornet", + "Carl", + "Raynor", + "Dixie", + "Wolnir", + "Mario", + "Gary", + "Wayne", + "Kevin", + "J.J.", + "Maxim", + "Redento", + "Caesar", + "Abigail", + "Link", + "Ninja", + "Roxas", + "Marin", + "Yorgle", + "DLC", + "Mina", + "Sans", + "Lan", + "Rin", + "Doomguy", + "Guide", +] + +totally_real_item_names = [ + "Mallet", + "Lava Rod", + "Master Knife", + "Slippers", + "Spade", + + "Progressive Car Upgrade", + "Bonus Token", + + "Shortnail", + "Runmaster", + + "Courage Form", + "Auto Courage", + "Donald Defender", + "Goofy Blizzard", + "Ultimate Weapon", + + "Song of the Sky Whale", + "Gryphon Shoes", + "Wing Key", + "Strength Anklet", + + "Hairclip", + + "Key of Wisdom", + + "Baking", + "Progressive Block Mining", + + "Jar", + "Whistle of Space", + "Rito Tunic", + + "Kitchen Sink", + + "Rock Badge", + "Key Card", + "Pikachu", + "Eevee", + "HM02 Strength", + + "Progressive Astromancers", + "Progressive Chefs", + "The Living Safe", + "Lady Quinn", + + "Dio's Worst Enemy", + + "Pink Chaos Emerald", + "Black Chaos Emerald", + "Tails - Large Cannon", + "Eggman - Bazooka", + "Eggman - Booster", + "Knuckles - Shades", + "Sonic - Magic Shoes", + "Shadow - Bounce Bracelet", + "Rouge - Air Necklace", + "Big Key (Eggman's Pyramid)", + + "Sensor Bunker", + "Phantom", + "Soldier", + + "Plasma Suit", + "Gravity Beam", + "Hi-Jump Ball", + + "Cannon Unlock LLL", + "Feather Cap", + + "Progressive Yoshi", + "Purple Switch Palace", + "Cape Feather", + + "Cane of Bryan", + + "Van Repair", + "Autumn", + "Galaxy Knife", + "Green Cabbage Seeds", + + "Timespinner Cog 1", + + "Ladder", + + "Visible Dots", +] + +all_exits = [ + 0x00, # Lobby to Neutral + 0x01, # Lobby to Hero + 0x02, # Lobby to Dark + 0x03, # Lobby to Kindergarten + 0x04, # Neutral to Lobby + 0x05, # Neutral to Cave + 0x06, # Neutral to Transporter + 0x07, # Hero to Lobby + 0x08, # Hero to Transporter + 0x09, # Dark to Lobby + 0x0A, # Dark to Transporter + 0x0B, # Cave to Neutral + 0x0C, # Cave to Race + 0x0D, # Cave to Karate + 0x0E, # Race to Cave + 0x0F, # Karate to Cave + 0x10, # Transporter to Neutral + #0x11, # Transporter to Hero + #0x12, # Transporter to Dark + 0x13, # Kindergarten to Lobby +] + +all_destinations = [ + 0x07, # Lobby + 0x07, + 0x07, + 0x07, + 0x01, # Neutral + 0x01, + 0x01, + 0x02, # Hero + 0x02, + 0x03, # Dark + 0x03, + 0x09, # Cave + 0x09, + 0x09, + 0x05, # Chao Race + 0x0A, # Chao Karate + 0x0C, # Transporter + #0x0C, + #0x0C, + 0x06, # Kindergarten +] + +multi_rooms = [ + 0x07, + 0x01, + 0x02, + 0x03, + 0x09, +] + +single_rooms = [ + 0x05, + 0x0A, + 0x0C, + 0x06, +] + +room_to_exits_map = { + 0x07: [0x00, 0x01, 0x02, 0x03], + 0x01: [0x04, 0x05, 0x06], + 0x02: [0x07, 0x08], + 0x03: [0x09, 0x0A], + 0x09: [0x0B, 0x0C, 0x0D], + 0x05: [0x0E], + 0x0A: [0x0F], + 0x0C: [0x10],#, 0x11, 0x12], + 0x06: [0x13], +} + +exit_to_room_map = { + 0x00: 0x07, # Lobby to Neutral + 0x01: 0x07, # Lobby to Hero + 0x02: 0x07, # Lobby to Dark + 0x03: 0x07, # Lobby to Kindergarten + 0x04: 0x01, # Neutral to Lobby + 0x05: 0x01, # Neutral to Cave + 0x06: 0x01, # Neutral to Transporter + 0x07: 0x02, # Hero to Lobby + 0x08: 0x02, # Hero to Transporter + 0x09: 0x03, # Dark to Lobby + 0x0A: 0x03, # Dark to Transporter + 0x0B: 0x09, # Cave to Neutral + 0x0C: 0x09, # Cave to Race + 0x0D: 0x09, # Cave to Karate + 0x0E: 0x05, # Race to Cave + 0x0F: 0x0A, # Karate to Cave + 0x10: 0x0C, # Transporter to Neutral + #0x11: 0x0C, # Transporter to Hero + #0x12: 0x0C, # Transporter to Dark + 0x13: 0x06, # Kindergarten to Lobby +} + +valid_kindergarten_exits = [ + 0x04, # Neutral to Lobby + 0x05, # Neutral to Cave + 0x07, # Hero to Lobby + 0x09, # Dark to Lobby +] diff --git a/worlds/sa2b/GateBosses.py b/worlds/sa2b/GateBosses.py index e89d4c45..76dd71fa 100644 --- a/worlds/sa2b/GateBosses.py +++ b/worlds/sa2b/GateBosses.py @@ -1,4 +1,6 @@ import typing +from BaseClasses import MultiWorld +from worlds.AutoWorld import World speed_characters_1 = "Sonic vs Shadow 1" speed_characters_2 = "Sonic vs Shadow 2" @@ -59,17 +61,17 @@ def boss_has_requirement(boss: int): return boss >= len(gate_bosses_no_requirements_table) -def get_gate_bosses(world, player: int): +def get_gate_bosses(multiworld: MultiWorld, world: World): selected_bosses: typing.List[int] = [] boss_gates: typing.List[int] = [] available_bosses: typing.List[str] = list(gate_bosses_no_requirements_table.keys()) - world.random.shuffle(available_bosses) + multiworld.random.shuffle(available_bosses) halfway = False - for x in range(world.number_of_level_gates[player]): - if (not halfway) and ((x + 1) / world.number_of_level_gates[player]) > 0.5: + for x in range(world.options.number_of_level_gates): + if (not halfway) and ((x + 1) / world.options.number_of_level_gates) > 0.5: available_bosses.extend(gate_bosses_with_requirements_table) - world.random.shuffle(available_bosses) + multiworld.random.shuffle(available_bosses) halfway = True selected_bosses.append(all_gate_bosses_table[available_bosses[0]]) boss_gates.append(x + 1) @@ -80,27 +82,27 @@ def get_gate_bosses(world, player: int): return bosses -def get_boss_rush_bosses(multiworld, player: int): +def get_boss_rush_bosses(multiworld: MultiWorld, world: World): - if multiworld.boss_rush_shuffle[player] == 0: + if world.options.boss_rush_shuffle == 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: + elif world.options.boss_rush_shuffle == 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: + elif world.options.boss_rush_shuffle == 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: + elif world.options.boss_rush_shuffle == 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: diff --git a/worlds/sa2b/Items.py b/worlds/sa2b/Items.py index 2b862c66..318a57f7 100644 --- a/worlds/sa2b/Items.py +++ b/worlds/sa2b/Items.py @@ -22,7 +22,8 @@ class SA2BItem(Item): # Separate tables for each type of item. emblems_table = { - ItemName.emblem: ItemData(0xFF0000, True), + ItemName.emblem: ItemData(0xFF0000, True), + ItemName.market_token: ItemData(0xFF001F, True), } upgrades_table = { @@ -82,6 +83,7 @@ trap_table = { ItemName.ice_trap: ItemData(0xFF0037, False, True), ItemName.slow_trap: ItemData(0xFF0038, False, True), ItemName.cutscene_trap: ItemData(0xFF0039, False, True), + ItemName.reverse_trap: ItemData(0xFF003A, False, True), ItemName.pong_trap: ItemData(0xFF0050, False, True), } @@ -96,6 +98,142 @@ emeralds_table = { ItemName.blue_emerald: ItemData(0xFF0046, True), } +eggs_table = { + ItemName.normal_egg: ItemData(0xFF0100, False), + ItemName.yellow_monotone_egg: ItemData(0xFF0101, False), + ItemName.white_monotone_egg: ItemData(0xFF0102, False), + ItemName.brown_monotone_egg: ItemData(0xFF0103, False), + ItemName.sky_blue_monotone_egg: ItemData(0xFF0104, False), + ItemName.pink_monotone_egg: ItemData(0xFF0105, False), + ItemName.blue_monotone_egg: ItemData(0xFF0106, False), + ItemName.grey_monotone_egg: ItemData(0xFF0107, False), + ItemName.green_monotone_egg: ItemData(0xFF0108, False), + ItemName.red_monotone_egg: ItemData(0xFF0109, False), + ItemName.lime_green_monotone_egg: ItemData(0xFF010A, False), + ItemName.purple_monotone_egg: ItemData(0xFF010B, False), + ItemName.orange_monotone_egg: ItemData(0xFF010C, False), + ItemName.black_monotone_egg: ItemData(0xFF010D, False), + + ItemName.yellow_twotone_egg: ItemData(0xFF010E, False), + ItemName.white_twotone_egg: ItemData(0xFF010F, False), + ItemName.brown_twotone_egg: ItemData(0xFF0110, False), + ItemName.sky_blue_twotone_egg: ItemData(0xFF0111, False), + ItemName.pink_twotone_egg: ItemData(0xFF0112, False), + ItemName.blue_twotone_egg: ItemData(0xFF0113, False), + ItemName.grey_twotone_egg: ItemData(0xFF0114, False), + ItemName.green_twotone_egg: ItemData(0xFF0115, False), + ItemName.red_twotone_egg: ItemData(0xFF0116, False), + ItemName.lime_green_twotone_egg: ItemData(0xFF0117, False), + ItemName.purple_twotone_egg: ItemData(0xFF0118, False), + ItemName.orange_twotone_egg: ItemData(0xFF0119, False), + ItemName.black_twotone_egg: ItemData(0xFF011A, False), + + ItemName.normal_shiny_egg: ItemData(0xFF011B, False), + ItemName.yellow_shiny_egg: ItemData(0xFF011C, False), + ItemName.white_shiny_egg: ItemData(0xFF011D, False), + ItemName.brown_shiny_egg: ItemData(0xFF011E, False), + ItemName.sky_blue_shiny_egg: ItemData(0xFF011F, False), + ItemName.pink_shiny_egg: ItemData(0xFF0120, False), + ItemName.blue_shiny_egg: ItemData(0xFF0121, False), + ItemName.grey_shiny_egg: ItemData(0xFF0122, False), + ItemName.green_shiny_egg: ItemData(0xFF0123, False), + ItemName.red_shiny_egg: ItemData(0xFF0124, False), + ItemName.lime_green_shiny_egg: ItemData(0xFF0125, False), + ItemName.purple_shiny_egg: ItemData(0xFF0126, False), + ItemName.orange_shiny_egg: ItemData(0xFF0127, False), + ItemName.black_shiny_egg: ItemData(0xFF0128, False), +} + +fruits_table = { + ItemName.chao_garden_fruit: ItemData(0xFF0200, False), + ItemName.hero_garden_fruit: ItemData(0xFF0201, False), + ItemName.dark_garden_fruit: ItemData(0xFF0202, False), + + ItemName.strong_fruit: ItemData(0xFF0203, False), + ItemName.tasty_fruit: ItemData(0xFF0204, False), + ItemName.hero_fruit: ItemData(0xFF0205, False), + ItemName.dark_fruit: ItemData(0xFF0206, False), + ItemName.round_fruit: ItemData(0xFF0207, False), + ItemName.triangle_fruit: ItemData(0xFF0208, False), + ItemName.square_fruit: ItemData(0xFF0209, False), + ItemName.heart_fruit: ItemData(0xFF020A, False), + ItemName.chao_fruit: ItemData(0xFF020B, False), + ItemName.smart_fruit: ItemData(0xFF020C, False), + + ItemName.orange_fruit: ItemData(0xFF020D, False), + ItemName.blue_fruit: ItemData(0xFF020E, False), + ItemName.pink_fruit: ItemData(0xFF020F, False), + ItemName.green_fruit: ItemData(0xFF0210, False), + ItemName.purple_fruit: ItemData(0xFF0211, False), + ItemName.yellow_fruit: ItemData(0xFF0212, False), + ItemName.red_fruit: ItemData(0xFF0213, False), + + ItemName.mushroom_fruit: ItemData(0xFF0214, False), + ItemName.super_mushroom_fruit: ItemData(0xFF0215, False), + ItemName.mint_candy_fruit: ItemData(0xFF0216, False), + ItemName.grapes_fruit: ItemData(0xFF0217, False), +} + +seeds_table = { + ItemName.strong_seed: ItemData(0xFF0300, False), + ItemName.tasty_seed: ItemData(0xFF0301, False), + ItemName.hero_seed: ItemData(0xFF0302, False), + ItemName.dark_seed: ItemData(0xFF0303, False), + ItemName.round_seed: ItemData(0xFF0304, False), + ItemName.triangle_seed: ItemData(0xFF0305, False), + ItemName.square_seed: ItemData(0xFF0306, False), +} + +hats_table = { + ItemName.pumpkin_hat: ItemData(0xFF0401, False), + ItemName.skull_hat: ItemData(0xFF0402, False), + ItemName.apple_hat: ItemData(0xFF0403, False), + ItemName.bucket_hat: ItemData(0xFF0404, False), + ItemName.empty_can_hat: ItemData(0xFF0405, False), + ItemName.cardboard_box_hat: ItemData(0xFF0406, False), + ItemName.flower_pot_hat: ItemData(0xFF0407, False), + ItemName.paper_bag_hat: ItemData(0xFF0408, False), + ItemName.pan_hat: ItemData(0xFF0409, False), + ItemName.stump_hat: ItemData(0xFF040A, False), + ItemName.watermelon_hat: ItemData(0xFF040B, False), + + ItemName.red_wool_beanie_hat: ItemData(0xFF040C, False), + ItemName.blue_wool_beanie_hat: ItemData(0xFF040D, False), + ItemName.black_wool_beanie_hat: ItemData(0xFF040E, False), + ItemName.pacifier_hat: ItemData(0xFF040F, False), +} + +animals_table = { + ItemName.animal_penguin: ItemData(0xFF0500, False), + ItemName.animal_seal: ItemData(0xFF0501, False), + ItemName.animal_otter: ItemData(0xFF0502, False), + ItemName.animal_rabbit: ItemData(0xFF0503, False), + ItemName.animal_cheetah: ItemData(0xFF0504, False), + ItemName.animal_warthog: ItemData(0xFF0505, False), + ItemName.animal_bear: ItemData(0xFF0506, False), + ItemName.animal_tiger: ItemData(0xFF0507, False), + ItemName.animal_gorilla: ItemData(0xFF0508, False), + ItemName.animal_peacock: ItemData(0xFF0509, False), + ItemName.animal_parrot: ItemData(0xFF050A, False), + ItemName.animal_condor: ItemData(0xFF050B, False), + ItemName.animal_skunk: ItemData(0xFF050C, False), + ItemName.animal_sheep: ItemData(0xFF050D, False), + ItemName.animal_raccoon: ItemData(0xFF050E, False), + ItemName.animal_halffish: ItemData(0xFF050F, False), + ItemName.animal_skeleton_dog: ItemData(0xFF0510, False), + ItemName.animal_bat: ItemData(0xFF0511, False), + ItemName.animal_dragon: ItemData(0xFF0512, False), + ItemName.animal_unicorn: ItemData(0xFF0513, False), + ItemName.animal_phoenix: ItemData(0xFF0514, False), +} + +chaos_drives_table = { + ItemName.chaos_drive_yellow: ItemData(0xFF0515, False), + ItemName.chaos_drive_green: ItemData(0xFF0516, False), + ItemName.chaos_drive_red: ItemData(0xFF0517, False), + ItemName.chaos_drive_purple: ItemData(0xFF0518, False), +} + event_table = { ItemName.maria: ItemData(0xFF001D, True), } @@ -107,12 +245,25 @@ item_table = { **junk_table, **trap_table, **emeralds_table, + **eggs_table, + **fruits_table, + **seeds_table, + **hats_table, + **animals_table, + **chaos_drives_table, **event_table, } lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in item_table.items() if data.code} -item_groups: typing.Dict[str, str] = {"Chaos Emeralds": [item_name for item_name, data in emeralds_table.items()]} +item_groups: typing.Dict[str, str] = { + "Chaos Emeralds": list(emeralds_table.keys()), + "Eggs": list(eggs_table.keys()), + "Fruits": list(fruits_table.keys()), + "Seeds": list(seeds_table.keys()), + "Hats": list(hats_table.keys()), + "Traps": list(trap_table.keys()), +} ALTTPWorld.pedestal_credit_texts[item_table[ItemName.sonic_light_shoes].code] = "and the Soap Shoes" ALTTPWorld.pedestal_credit_texts[item_table[ItemName.shadow_air_shoes].code] = "and the Soap Shoes" diff --git a/worlds/sa2b/Locations.py b/worlds/sa2b/Locations.py index 461580bb..c928e0c3 100644 --- a/worlds/sa2b/Locations.py +++ b/worlds/sa2b/Locations.py @@ -1,6 +1,7 @@ import typing from BaseClasses import Location, MultiWorld +from worlds.AutoWorld import World from .Names import LocationName from .Missions import stage_name_prefixes, mission_orders @@ -1066,6 +1067,7 @@ animal_location_table = { LocationName.final_rush_animal_11: 0xFF0C4F, LocationName.iron_gate_animal_11: 0xFF0C50, + LocationName.dry_lagoon_animal_11: 0xFF0C51, LocationName.sand_ocean_animal_11: 0xFF0C52, LocationName.radical_highway_animal_11: 0xFF0C53, LocationName.lost_colony_animal_11: 0xFF0C55, @@ -1241,7 +1243,7 @@ boss_rush_location_table = { LocationName.boss_rush_16: 0xFF0114, } -chao_garden_beginner_location_table = { +chao_race_beginner_location_table = { LocationName.chao_race_crab_pool_1: 0xFF0200, LocationName.chao_race_crab_pool_2: 0xFF0201, LocationName.chao_race_crab_pool_3: 0xFF0202, @@ -1254,11 +1256,17 @@ chao_garden_beginner_location_table = { LocationName.chao_race_block_canyon_1: 0xFF0209, LocationName.chao_race_block_canyon_2: 0xFF020A, LocationName.chao_race_block_canyon_3: 0xFF020B, - - LocationName.chao_beginner_karate: 0xFF0300, } -chao_garden_intermediate_location_table = { +chao_karate_beginner_location_table = { + LocationName.chao_beginner_karate_1: 0xFF0300, + LocationName.chao_beginner_karate_2: 0xFF0301, + LocationName.chao_beginner_karate_3: 0xFF0302, + LocationName.chao_beginner_karate_4: 0xFF0303, + LocationName.chao_beginner_karate_5: 0xFF0304, +} + +chao_race_intermediate_location_table = { LocationName.chao_race_challenge_1: 0xFF022A, LocationName.chao_race_challenge_2: 0xFF022B, LocationName.chao_race_challenge_3: 0xFF022C, @@ -1281,11 +1289,17 @@ chao_garden_intermediate_location_table = { LocationName.chao_race_dark_2: 0xFF023B, LocationName.chao_race_dark_3: 0xFF023C, LocationName.chao_race_dark_4: 0xFF023D, - - LocationName.chao_standard_karate: 0xFF0301, } -chao_garden_expert_location_table = { +chao_karate_intermediate_location_table = { + LocationName.chao_standard_karate_1: 0xFF0305, + LocationName.chao_standard_karate_2: 0xFF0306, + LocationName.chao_standard_karate_3: 0xFF0307, + LocationName.chao_standard_karate_4: 0xFF0308, + LocationName.chao_standard_karate_5: 0xFF0309, +} + +chao_race_expert_location_table = { LocationName.chao_race_aquamarine_1: 0xFF020C, LocationName.chao_race_aquamarine_2: 0xFF020D, LocationName.chao_race_aquamarine_3: 0xFF020E, @@ -1316,11 +1330,187 @@ chao_garden_expert_location_table = { LocationName.chao_race_diamond_3: 0xFF0227, LocationName.chao_race_diamond_4: 0xFF0228, LocationName.chao_race_diamond_5: 0xFF0229, - - LocationName.chao_expert_karate: 0xFF0302, - LocationName.chao_super_karate: 0xFF0303, } +chao_karate_expert_location_table = { + LocationName.chao_expert_karate_1: 0xFF030A, + LocationName.chao_expert_karate_2: 0xFF030B, + LocationName.chao_expert_karate_3: 0xFF030C, + LocationName.chao_expert_karate_4: 0xFF030D, + LocationName.chao_expert_karate_5: 0xFF030E, +} + +chao_karate_super_location_table = { + LocationName.chao_super_karate_1: 0xFF030F, + LocationName.chao_super_karate_2: 0xFF0310, + LocationName.chao_super_karate_3: 0xFF0311, + LocationName.chao_super_karate_4: 0xFF0312, + LocationName.chao_super_karate_5: 0xFF0313, +} + +chao_stat_swim_table = { LocationName.chao_stat_swim_base + str(index): (0xFF0E00 + index) for index in range(1,100) } +chao_stat_fly_table = { LocationName.chao_stat_fly_base + str(index): (0xFF0E80 + index) for index in range(1,100) } +chao_stat_run_table = { LocationName.chao_stat_run_base + str(index): (0xFF0F00 + index) for index in range(1,100) } +chao_stat_power_table = { LocationName.chao_stat_power_base + str(index): (0xFF0F80 + index) for index in range(1,100) } +chao_stat_stamina_table = { LocationName.chao_stat_stamina_base + str(index): (0xFF1000 + index) for index in range(1,100) } +chao_stat_luck_table = { LocationName.chao_stat_luck_base + str(index): (0xFF1080 + index) for index in range(1,100) } +chao_stat_intelligence_table = { LocationName.chao_stat_intelligence_base + str(index): (0xFF1100 + index) for index in range(1,100) } + +chao_animal_event_location_table = { + LocationName.animal_penguin: None, + LocationName.animal_seal: None, + LocationName.animal_otter: None, + LocationName.animal_rabbit: None, + LocationName.animal_cheetah: None, + LocationName.animal_warthog: None, + LocationName.animal_bear: None, + LocationName.animal_tiger: None, + LocationName.animal_gorilla: None, + LocationName.animal_peacock: None, + LocationName.animal_parrot: None, + LocationName.animal_condor: None, + LocationName.animal_skunk: None, + LocationName.animal_sheep: None, + LocationName.animal_raccoon: None, + LocationName.animal_halffish: None, + LocationName.animal_skeleton_dog: None, + LocationName.animal_bat: None, + LocationName.animal_dragon: None, + LocationName.animal_unicorn: None, + LocationName.animal_phoenix: None, +} + +chao_animal_part_location_table = { + LocationName.chao_penguin_arms: 0xFF1220, + LocationName.chao_penguin_forehead: 0xFF1222, + LocationName.chao_penguin_legs: 0xFF1224, + + LocationName.chao_seal_arms: 0xFF1228, + LocationName.chao_seal_tail: 0xFF122E, + + LocationName.chao_otter_arms: 0xFF1230, + LocationName.chao_otter_ears: 0xFF1231, + LocationName.chao_otter_face: 0xFF1233, + LocationName.chao_otter_legs: 0xFF1234, + LocationName.chao_otter_tail: 0xFF1236, + + LocationName.chao_rabbit_arms: 0xFF1238, + LocationName.chao_rabbit_ears: 0xFF1239, + LocationName.chao_rabbit_legs: 0xFF123C, + LocationName.chao_rabbit_tail: 0xFF123E, + + LocationName.chao_cheetah_arms: 0xFF1240, + LocationName.chao_cheetah_ears: 0xFF1241, + LocationName.chao_cheetah_legs: 0xFF1244, + LocationName.chao_cheetah_tail: 0xFF1246, + + LocationName.chao_warthog_arms: 0xFF1248, + LocationName.chao_warthog_ears: 0xFF1249, + LocationName.chao_warthog_face: 0xFF124B, + LocationName.chao_warthog_legs: 0xFF124C, + LocationName.chao_warthog_tail: 0xFF124E, + + LocationName.chao_bear_arms: 0xFF1250, + LocationName.chao_bear_ears: 0xFF1251, + LocationName.chao_bear_legs: 0xFF1254, + + LocationName.chao_tiger_arms: 0xFF1258, + LocationName.chao_tiger_ears: 0xFF1259, + LocationName.chao_tiger_legs: 0xFF125C, + LocationName.chao_tiger_tail: 0xFF125E, + + LocationName.chao_gorilla_arms: 0xFF1260, + LocationName.chao_gorilla_ears: 0xFF1261, + LocationName.chao_gorilla_forehead: 0xFF1262, + LocationName.chao_gorilla_legs: 0xFF1264, + + LocationName.chao_peacock_forehead: 0xFF126A, + LocationName.chao_peacock_legs: 0xFF126C, + LocationName.chao_peacock_tail: 0xFF126E, + LocationName.chao_peacock_wings: 0xFF126F, + + LocationName.chao_parrot_forehead: 0xFF1272, + LocationName.chao_parrot_legs: 0xFF1274, + LocationName.chao_parrot_tail: 0xFF1276, + LocationName.chao_parrot_wings: 0xFF1277, + + LocationName.chao_condor_ears: 0xFF1279, + LocationName.chao_condor_legs: 0xFF127C, + LocationName.chao_condor_tail: 0xFF127E, + LocationName.chao_condor_wings: 0xFF127F, + + LocationName.chao_skunk_arms: 0xFF1280, + LocationName.chao_skunk_forehead: 0xFF1282, + LocationName.chao_skunk_legs: 0xFF1284, + LocationName.chao_skunk_tail: 0xFF1286, + + LocationName.chao_sheep_arms: 0xFF1288, + LocationName.chao_sheep_ears: 0xFF1289, + LocationName.chao_sheep_legs: 0xFF128C, + LocationName.chao_sheep_horn: 0xFF128D, + LocationName.chao_sheep_tail: 0xFF128E, + + LocationName.chao_raccoon_arms: 0xFF1290, + LocationName.chao_raccoon_ears: 0xFF1291, + LocationName.chao_raccoon_legs: 0xFF1294, + + LocationName.chao_dragon_arms: 0xFF12A0, + LocationName.chao_dragon_ears: 0xFF12A1, + LocationName.chao_dragon_legs: 0xFF12A4, + LocationName.chao_dragon_horn: 0xFF12A5, + LocationName.chao_dragon_tail: 0xFF12A6, + LocationName.chao_dragon_wings: 0xFF12A7, + + LocationName.chao_unicorn_arms: 0xFF12A8, + LocationName.chao_unicorn_ears: 0xFF12A9, + LocationName.chao_unicorn_forehead: 0xFF12AA, + LocationName.chao_unicorn_legs: 0xFF12AC, + LocationName.chao_unicorn_tail: 0xFF12AE, + + LocationName.chao_phoenix_forehead: 0xFF12B2, + LocationName.chao_phoenix_legs: 0xFF12B4, + LocationName.chao_phoenix_tail: 0xFF12B6, + LocationName.chao_phoenix_wings: 0xFF12B7, +} + +chao_kindergarten_location_table = { + LocationName.chao_kindergarten_drawing_1: 0xFF12D0, + LocationName.chao_kindergarten_drawing_2: 0xFF12D1, + LocationName.chao_kindergarten_drawing_3: 0xFF12D2, + LocationName.chao_kindergarten_drawing_4: 0xFF12D3, + LocationName.chao_kindergarten_drawing_5: 0xFF12D4, + + LocationName.chao_kindergarten_shake_dance: 0xFF12D8, + LocationName.chao_kindergarten_spin_dance: 0xFF12D9, + LocationName.chao_kindergarten_step_dance: 0xFF12DA, + LocationName.chao_kindergarten_gogo_dance: 0xFF12DB, + LocationName.chao_kindergarten_exercise: 0xFF12DC, + + LocationName.chao_kindergarten_song_1: 0xFF12E0, + LocationName.chao_kindergarten_song_2: 0xFF12E1, + LocationName.chao_kindergarten_song_3: 0xFF12E2, + LocationName.chao_kindergarten_song_4: 0xFF12E3, + LocationName.chao_kindergarten_song_5: 0xFF12E4, + + LocationName.chao_kindergarten_bell: 0xFF12E8, + LocationName.chao_kindergarten_castanets: 0xFF12E9, + LocationName.chao_kindergarten_cymbals: 0xFF12EA, + LocationName.chao_kindergarten_drum: 0xFF12EB, + LocationName.chao_kindergarten_flute: 0xFF12EC, + LocationName.chao_kindergarten_maracas: 0xFF12ED, + LocationName.chao_kindergarten_trumpet: 0xFF12EE, + LocationName.chao_kindergarten_tambourine: 0xFF12EF, +} + +chao_kindergarten_basics_location_table = { + LocationName.chao_kindergarten_any_drawing: 0xFF12F0, + LocationName.chao_kindergarten_any_dance: 0xFF12F1, + LocationName.chao_kindergarten_any_song: 0xFF12F2, + LocationName.chao_kindergarten_any_instrument: 0xFF12F3, +} + +black_market_location_table = { LocationName.chao_black_market_base + str(index): (0xFF1300 + index) for index in range(1,65) } + kart_race_beginner_location_table = { LocationName.kart_race_beginner_sonic: 0xFF0A00, LocationName.kart_race_beginner_tails: 0xFF0A01, @@ -1375,6 +1565,10 @@ grand_prix_location_table = { LocationName.grand_prix: 0xFF007F, } +chaos_chao_location_table = { + LocationName.chaos_chao: 0xFF009F, +} + all_locations = { **mission_location_table, **upgrade_location_table, @@ -1386,9 +1580,13 @@ all_locations = { **beetle_location_table, **omochao_location_table, **animal_location_table, - **chao_garden_beginner_location_table, - **chao_garden_intermediate_location_table, - **chao_garden_expert_location_table, + **chao_race_beginner_location_table, + **chao_karate_beginner_location_table, + **chao_race_intermediate_location_table, + **chao_karate_intermediate_location_table, + **chao_race_expert_location_table, + **chao_karate_expert_location_table, + **chao_karate_super_location_table, **kart_race_beginner_location_table, **kart_race_standard_location_table, **kart_race_expert_location_table, @@ -1398,6 +1596,18 @@ all_locations = { **green_hill_animal_location_table, **final_boss_location_table, **grand_prix_location_table, + **chaos_chao_location_table, + **chao_stat_swim_table, + **chao_stat_fly_table, + **chao_stat_run_table, + **chao_stat_power_table, + **chao_stat_stamina_table, + **chao_stat_luck_table, + **chao_stat_intelligence_table, + **chao_animal_part_location_table, + **chao_kindergarten_location_table, + **chao_kindergarten_basics_location_table, + **black_market_location_table, } boss_gate_set = [ @@ -1408,13 +1618,6 @@ boss_gate_set = [ LocationName.gate_5_boss, ] -chao_karate_set = [ - LocationName.chao_beginner_karate, - LocationName.chao_standard_karate, - LocationName.chao_expert_karate, - LocationName.chao_super_karate, -] - chao_race_prize_set = [ LocationName.chao_race_crab_pool_3, LocationName.chao_race_stump_valley_3, @@ -1437,19 +1640,24 @@ chao_race_prize_set = [ LocationName.chao_race_dark_2, LocationName.chao_race_dark_4, + + LocationName.chao_beginner_karate_5, + LocationName.chao_standard_karate_5, + LocationName.chao_expert_karate_5, + LocationName.chao_super_karate_5, ] -def setup_locations(world: MultiWorld, player: int, mission_map: typing.Dict[int, int], mission_count_map: typing.Dict[int, int]): +def setup_locations(world: World, player: int, mission_map: typing.Dict[int, int], mission_count_map: typing.Dict[int, int]): location_table = {} chao_location_table = {} - if world.goal[player] == 3: - if world.kart_race_checks[player] == 2: + if world.options.goal == 3: + if world.options.kart_race_checks == 2: location_table.update({**kart_race_beginner_location_table}) location_table.update({**kart_race_standard_location_table}) location_table.update({**kart_race_expert_location_table}) - elif world.kart_race_checks[player] == 1: + elif world.options.kart_race_checks == 1: location_table.update({**kart_race_mini_location_table}) location_table.update({**grand_prix_location_table}) else: @@ -1465,67 +1673,100 @@ def setup_locations(world: MultiWorld, player: int, mission_map: typing.Dict[int location_table.update({**upgrade_location_table}) - if world.keysanity[player]: + if world.options.keysanity: location_table.update({**chao_key_location_table}) - if world.whistlesanity[player].value == 1: + if world.options.whistlesanity.value == 1: location_table.update({**pipe_location_table}) - elif world.whistlesanity[player].value == 2: + elif world.options.whistlesanity.value == 2: location_table.update({**hidden_whistle_location_table}) - elif world.whistlesanity[player].value == 3: + elif world.options.whistlesanity.value == 3: location_table.update({**pipe_location_table}) location_table.update({**hidden_whistle_location_table}) - if world.beetlesanity[player]: + if world.options.beetlesanity: location_table.update({**beetle_location_table}) - if world.omosanity[player]: + if world.options.omosanity: location_table.update({**omochao_location_table}) - if world.animalsanity[player]: + if world.options.animalsanity: location_table.update({**animal_location_table}) - if world.kart_race_checks[player] == 2: + if world.options.kart_race_checks == 2: location_table.update({**kart_race_beginner_location_table}) location_table.update({**kart_race_standard_location_table}) location_table.update({**kart_race_expert_location_table}) - elif world.kart_race_checks[player] == 1: + elif world.options.kart_race_checks == 1: location_table.update({**kart_race_mini_location_table}) - if world.goal[player].value in [0, 2, 4, 5, 6]: + if world.options.goal.value in [0, 2, 4, 5, 6]: location_table.update({**final_boss_location_table}) + elif world.options.goal.value in [7]: + location_table.update({**chaos_chao_location_table}) - if world.goal[player].value in [1, 2]: + if world.options.goal.value in [1, 2]: location_table.update({**green_hill_location_table}) - if world.keysanity[player]: + if world.options.keysanity: location_table.update({**green_hill_chao_location_table}) - if world.animalsanity[player]: + if world.options.animalsanity: location_table.update({**green_hill_animal_location_table}) - if world.goal[player].value in [4, 5, 6]: + if world.options.goal.value in [4, 5, 6]: location_table.update({**boss_rush_location_table}) - if world.chao_garden_difficulty[player].value >= 1: - chao_location_table.update({**chao_garden_beginner_location_table}) - if world.chao_garden_difficulty[player].value >= 2: - chao_location_table.update({**chao_garden_intermediate_location_table}) - if world.chao_garden_difficulty[player].value >= 3: - chao_location_table.update({**chao_garden_expert_location_table}) + if world.options.chao_race_difficulty.value >= 1: + chao_location_table.update({**chao_race_beginner_location_table}) + if world.options.chao_race_difficulty.value >= 2: + chao_location_table.update({**chao_race_intermediate_location_table}) + if world.options.chao_race_difficulty.value >= 3: + chao_location_table.update({**chao_race_expert_location_table}) + + if world.options.chao_karate_difficulty.value >= 1: + chao_location_table.update({**chao_karate_beginner_location_table}) + if world.options.chao_karate_difficulty.value >= 2: + chao_location_table.update({**chao_karate_intermediate_location_table}) + if world.options.chao_karate_difficulty.value >= 3: + chao_location_table.update({**chao_karate_expert_location_table}) + if world.options.chao_karate_difficulty.value >= 4: + chao_location_table.update({**chao_karate_super_location_table}) for key, value in chao_location_table.items(): - if key in chao_karate_set: - if world.include_chao_karate[player]: - location_table[key] = value - elif key not in chao_race_prize_set: - if world.chao_race_checks[player] == "all": + if key not in chao_race_prize_set: + if world.options.chao_stadium_checks == "all": location_table[key] = value else: location_table[key] = value + for index in range(1, world.options.chao_stats.value + 1): + if (index % world.options.chao_stats_frequency.value) == (world.options.chao_stats.value % world.options.chao_stats_frequency.value): + location_table[LocationName.chao_stat_swim_base + str(index)] = chao_stat_swim_table[ LocationName.chao_stat_swim_base + str(index)] + location_table[LocationName.chao_stat_fly_base + str(index)] = chao_stat_fly_table[ LocationName.chao_stat_fly_base + str(index)] + location_table[LocationName.chao_stat_run_base + str(index)] = chao_stat_run_table[ LocationName.chao_stat_run_base + str(index)] + location_table[LocationName.chao_stat_power_base + str(index)] = chao_stat_power_table[ LocationName.chao_stat_power_base + str(index)] + + if world.options.chao_stats_stamina: + location_table[LocationName.chao_stat_stamina_base + str(index)] = chao_stat_stamina_table[LocationName.chao_stat_stamina_base + str(index)] + + if world.options.chao_stats_hidden: + location_table[LocationName.chao_stat_luck_base + str(index)] = chao_stat_luck_table[ LocationName.chao_stat_luck_base + str(index)] + location_table[LocationName.chao_stat_intelligence_base + str(index)] = chao_stat_intelligence_table[LocationName.chao_stat_intelligence_base + str(index)] + + if world.options.chao_animal_parts: + location_table.update({**chao_animal_part_location_table}) + + if world.options.chao_kindergarten.value == 1: + location_table.update({**chao_kindergarten_basics_location_table}) + elif world.options.chao_kindergarten.value == 2: + location_table.update({**chao_kindergarten_location_table}) + + for index in range(1, world.options.black_market_slots.value + 1): + location_table[LocationName.chao_black_market_base + str(index)] = black_market_location_table[LocationName.chao_black_market_base + str(index)] + for x in range(len(boss_gate_set)): - if x < world.number_of_level_gates[player].value: + if x < world.options.number_of_level_gates.value: location_table[boss_gate_set[x]] = boss_gate_location_table[boss_gate_set[x]] return location_table diff --git a/worlds/sa2b/Missions.py b/worlds/sa2b/Missions.py index 1fcd2aed..5ee48d56 100644 --- a/worlds/sa2b/Missions.py +++ b/worlds/sa2b/Missions.py @@ -2,6 +2,7 @@ import typing import copy from BaseClasses import MultiWorld +from worlds.AutoWorld import World mission_orders: typing.List[typing.List[int]] = [ @@ -193,10 +194,10 @@ stage_name_prefixes: typing.List[str] = [ "Cannon's Core - ", ] -def get_mission_count_table(multiworld: MultiWorld, player: int): +def get_mission_count_table(multiworld: MultiWorld, world: World, player: int): mission_count_table: typing.Dict[int, int] = {} - if multiworld.goal[player] == 3: + if world.options.goal == 3: for level in range(31): mission_count_table[level] = 0 else: @@ -207,26 +208,26 @@ def get_mission_count_table(multiworld: MultiWorld, player: int): cannons_core_active_missions = 1 for i in range(2,6): - if getattr(multiworld, "speed_mission_" + str(i), None)[player]: + if getattr(world.options, "speed_mission_" + str(i), None): speed_active_missions += 1 - if getattr(multiworld, "mech_mission_" + str(i), None)[player]: + if getattr(world.options, "mech_mission_" + str(i), None): mech_active_missions += 1 - if getattr(multiworld, "hunt_mission_" + str(i), None)[player]: + if getattr(world.options, "hunt_mission_" + str(i), None): hunt_active_missions += 1 - if getattr(multiworld, "kart_mission_" + str(i), None)[player]: + if getattr(world.options, "kart_mission_" + str(i), None): kart_active_missions += 1 - if getattr(multiworld, "cannons_core_mission_" + str(i), None)[player]: + if getattr(world.options, "cannons_core_mission_" + str(i), None): cannons_core_active_missions += 1 - speed_active_missions = min(speed_active_missions, multiworld.speed_mission_count[player].value) - mech_active_missions = min(mech_active_missions, multiworld.mech_mission_count[player].value) - hunt_active_missions = min(hunt_active_missions, multiworld.hunt_mission_count[player].value) - kart_active_missions = min(kart_active_missions, multiworld.kart_mission_count[player].value) - cannons_core_active_missions = min(cannons_core_active_missions, multiworld.cannons_core_mission_count[player].value) + speed_active_missions = min(speed_active_missions, world.options.speed_mission_count.value) + mech_active_missions = min(mech_active_missions, world.options.mech_mission_count.value) + hunt_active_missions = min(hunt_active_missions, world.options.hunt_mission_count.value) + kart_active_missions = min(kart_active_missions, world.options.kart_mission_count.value) + cannons_core_active_missions = min(cannons_core_active_missions, world.options.cannons_core_mission_count.value) active_missions: typing.List[typing.List[int]] = [ speed_active_missions, @@ -244,10 +245,10 @@ def get_mission_count_table(multiworld: MultiWorld, player: int): return mission_count_table -def get_mission_table(multiworld: MultiWorld, player: int): +def get_mission_table(multiworld: MultiWorld, world: World, player: int): mission_table: typing.Dict[int, int] = {} - if multiworld.goal[player] == 3: + if world.options.goal == 3: for level in range(31): mission_table[level] = 0 else: @@ -259,19 +260,19 @@ def get_mission_table(multiworld: MultiWorld, player: int): # Add included missions for i in range(2,6): - if getattr(multiworld, "speed_mission_" + str(i), None)[player]: + if getattr(world.options, "speed_mission_" + str(i), None): speed_active_missions.append(i) - if getattr(multiworld, "mech_mission_" + str(i), None)[player]: + if getattr(world.options, "mech_mission_" + str(i), None): mech_active_missions.append(i) - if getattr(multiworld, "hunt_mission_" + str(i), None)[player]: + if getattr(world.options, "hunt_mission_" + str(i), None): hunt_active_missions.append(i) - if getattr(multiworld, "kart_mission_" + str(i), None)[player]: + if getattr(world.options, "kart_mission_" + str(i), None): kart_active_missions.append(i) - if getattr(multiworld, "cannons_core_mission_" + str(i), None)[player]: + if getattr(world.options, "cannons_core_mission_" + str(i), None): cannons_core_active_missions.append(i) active_missions: typing.List[typing.List[int]] = [ @@ -292,10 +293,10 @@ def get_mission_table(multiworld: MultiWorld, player: int): first_mission = 1 first_mission_options = [1, 2, 3] - if not multiworld.animalsanity[player]: + if not world.options.animalsanity: first_mission_options.append(4) - if multiworld.mission_shuffle[player]: + if world.options.mission_shuffle: first_mission = multiworld.random.choice([mission for mission in level_active_missions if mission in first_mission_options]) level_active_missions.remove(first_mission) @@ -305,7 +306,7 @@ def get_mission_table(multiworld: MultiWorld, player: int): if mission not in level_chosen_missions: level_chosen_missions.append(mission) - if multiworld.mission_shuffle[player]: + if world.options.mission_shuffle: multiworld.random.shuffle(level_chosen_missions) level_chosen_missions.insert(0, first_mission) diff --git a/worlds/sa2b/Names/ItemName.py b/worlds/sa2b/Names/ItemName.py index eb088ceb..c6de9818 100644 --- a/worlds/sa2b/Names/ItemName.py +++ b/worlds/sa2b/Names/ItemName.py @@ -1,6 +1,9 @@ # Emblem Definition emblem = "Emblem" +# Market Token Definition +market_token = "Chao Coin" + # Upgrade Definitions sonic_gloves = "Sonic - Magic Glove" sonic_light_shoes = "Sonic - Light Shoes" @@ -36,6 +39,8 @@ rouge_pick_nails = "Rouge - Pick Nails" rouge_treasure_scope = "Rouge - Treasure Scope" rouge_iron_boots = "Rouge - Iron Boots" + +# Junk five_rings = "Five Rings" ten_rings = "Ten Rings" twenty_rings = "Twenty Rings" @@ -44,6 +49,8 @@ shield = "Shield" magnetic_shield = "Magnetic Shield" invincibility = "Invincibility" + +# Traps omochao_trap = "OmoTrap" timestop_trap = "Chaos Control Trap" confuse_trap = "Confusion Trap" @@ -54,9 +61,12 @@ darkness_trap = "Darkness Trap" ice_trap = "Ice Trap" slow_trap = "Slow Trap" cutscene_trap = "Cutscene Trap" +reverse_trap = "Reverse Trap" pong_trap = "Pong Trap" + +# Chaos Emeralds white_emerald = "White Chaos Emerald" red_emerald = "Red Chaos Emerald" cyan_emerald = "Cyan Chaos Emerald" @@ -65,4 +75,140 @@ green_emerald = "Green Chaos Emerald" yellow_emerald = "Yellow Chaos Emerald" blue_emerald = "Blue Chaos Emerald" + +# Chao Eggs +normal_egg = "Normal Egg" +yellow_monotone_egg = "Yellow Mono-Tone Egg" +white_monotone_egg = "White Mono-Tone Egg" +brown_monotone_egg = "Brown Mono-Tone Egg" +sky_blue_monotone_egg = "Sky Blue Mono-Tone Egg" +pink_monotone_egg = "Pink Mono-Tone Egg" +blue_monotone_egg = "Blue Mono-Tone Egg" +grey_monotone_egg = "Grey Mono-Tone Egg" +green_monotone_egg = "Green Mono-Tone Egg" +red_monotone_egg = "Red Mono-Tone Egg" +lime_green_monotone_egg = "Lime Green Mono-Tone Egg" +purple_monotone_egg = "Purple Mono-Tone Egg" +orange_monotone_egg = "Orange Mono-Tone Egg" +black_monotone_egg = "Black Mono-Tone Egg" + +yellow_twotone_egg = "Yellow Two-Tone Egg" +white_twotone_egg = "White Two-Tone Egg" +brown_twotone_egg = "Brown Two-Tone Egg" +sky_blue_twotone_egg = "Sky Blue Two-Tone Egg" +pink_twotone_egg = "Pink Two-Tone Egg" +blue_twotone_egg = "Blue Two-Tone Egg" +grey_twotone_egg = "Grey Two-Tone Egg" +green_twotone_egg = "Green Two-Tone Egg" +red_twotone_egg = "Red Two-Tone Egg" +lime_green_twotone_egg = "Lime Green Two-Tone Egg" +purple_twotone_egg = "Purple Two-Tone Egg" +orange_twotone_egg = "Orange Two-Tone Egg" +black_twotone_egg = "Black Two-Tone Egg" + +normal_shiny_egg = "Normal Shiny Egg" +yellow_shiny_egg = "Yellow Shiny Egg" +white_shiny_egg = "White Shiny Egg" +brown_shiny_egg = "Brown Shiny Egg" +sky_blue_shiny_egg = "Sky Blue Shiny Egg" +pink_shiny_egg = "Pink Shiny Egg" +blue_shiny_egg = "Blue Shiny Egg" +grey_shiny_egg = "Grey Shiny Egg" +green_shiny_egg = "Green Shiny Egg" +red_shiny_egg = "Red Shiny Egg" +lime_green_shiny_egg = "Lime Green Shiny Egg" +purple_shiny_egg = "Purple Shiny Egg" +orange_shiny_egg = "Orange Shiny Egg" +black_shiny_egg = "Black Shiny Egg" + + +# Chao Fruit +chao_garden_fruit = "Chao Garden Fruit" +hero_garden_fruit = "Hero Garden Fruit" +dark_garden_fruit = "Dark Garden Fruit" + +strong_fruit = "Strong Fruit" +tasty_fruit = "Tasty Fruit" +hero_fruit = "Hero Fruit" +dark_fruit = "Dark Fruit" +round_fruit = "Round Fruit" +triangle_fruit = "Triangle Fruit" +square_fruit = "Square Fruit" +heart_fruit = "Heart Fruit" +chao_fruit = "Chao Fruit" +smart_fruit = "Smart Fruit" + +orange_fruit = "Orange Fruit" +blue_fruit = "Blue Fruit" +pink_fruit = "Pink Fruit" +green_fruit = "Green Fruit" +purple_fruit = "Purple Fruit" +yellow_fruit = "Yellow Fruit" +red_fruit = "Red Fruit" + +mushroom_fruit = "Mushroom" +super_mushroom_fruit = "Super Mushroom" +mint_candy_fruit = "Mint Candy" +grapes_fruit = "Grapes" + + +# Chao Seeds +strong_seed = "Strong Seed" +tasty_seed = "Tasty Seed" +hero_seed = "Hero Seed" +dark_seed = "Dark Seed" +round_seed = "Round Seed" +triangle_seed = "Triangle Seed" +square_seed = "Square Seed" + + +# Chao Hats +pumpkin_hat = "Pumpkin" +skull_hat = "Skull" +apple_hat = "Apple" +bucket_hat = "Bucket" +empty_can_hat = "Empty Can" +cardboard_box_hat = "Cardboard Box" +flower_pot_hat = "Flower Pot" +paper_bag_hat = "Paper Bag" +pan_hat = "Pan" +stump_hat = "Stump" +watermelon_hat = "Watermelon" + +red_wool_beanie_hat = "Red Wool Beanie" +blue_wool_beanie_hat = "Blue Wool Beanie" +black_wool_beanie_hat = "Black Wool Beanie" +pacifier_hat = "Pacifier" + + +# Animal Items +animal_penguin = "Penguin" +animal_seal = "Seal" +animal_otter = "Otter" +animal_rabbit = "Rabbit" +animal_cheetah = "Cheetah" +animal_warthog = "Warthog" +animal_bear = "Bear" +animal_tiger = "Tiger" +animal_gorilla = "Gorilla" +animal_peacock = "Peacock" +animal_parrot = "Parrot" +animal_condor = "Condor" +animal_skunk = "Skunk" +animal_sheep = "Sheep" +animal_raccoon = "Raccoon" +animal_halffish = "HalfFish" +animal_skeleton_dog = "Skeleton Dog" +animal_bat = "Bat" +animal_dragon = "Dragon" +animal_unicorn = "Unicorn" +animal_phoenix = "Phoenix" + +chaos_drive_yellow = "Yellow Chaos Drive" +chaos_drive_green = "Green Chaos Drive" +chaos_drive_red = "Red Chaos Drive" +chaos_drive_purple = "Purple Chaos Drive" + + +# Goal Item maria = "What Maria Wanted" diff --git a/worlds/sa2b/Names/LocationName.py b/worlds/sa2b/Names/LocationName.py index f0638430..bde25a8a 100644 --- a/worlds/sa2b/Names/LocationName.py +++ b/worlds/sa2b/Names/LocationName.py @@ -909,6 +909,7 @@ dry_lagoon_animal_7 = "Dry Lagoon - 7 Animals" dry_lagoon_animal_8 = "Dry Lagoon - 8 Animals" dry_lagoon_animal_9 = "Dry Lagoon - 9 Animals" dry_lagoon_animal_10 = "Dry Lagoon - 10 Animals" +dry_lagoon_animal_11 = "Dry Lagoon - 11 Animals" dry_lagoon_upgrade = "Dry Lagoon - Upgrade" egg_quarters_1 = "Egg Quarters - 1" egg_quarters_2 = "Egg Quarters - 2" @@ -1150,10 +1151,190 @@ chao_race_dark_2 = "Chao Race - Dark 2" chao_race_dark_3 = "Chao Race - Dark 3" chao_race_dark_4 = "Chao Race - Dark 4" -chao_beginner_karate = "Chao Karate - Beginner" -chao_standard_karate = "Chao Karate - Standard" -chao_expert_karate = "Chao Karate - Expert" -chao_super_karate = "Chao Karate - Super" +chao_beginner_karate_1 = "Chao Karate - Beginner 1" +chao_beginner_karate_2 = "Chao Karate - Beginner 2" +chao_beginner_karate_3 = "Chao Karate - Beginner 3" +chao_beginner_karate_4 = "Chao Karate - Beginner 4" +chao_beginner_karate_5 = "Chao Karate - Beginner 5" +chao_standard_karate_1 = "Chao Karate - Standard 1" +chao_standard_karate_2 = "Chao Karate - Standard 2" +chao_standard_karate_3 = "Chao Karate - Standard 3" +chao_standard_karate_4 = "Chao Karate - Standard 4" +chao_standard_karate_5 = "Chao Karate - Standard 5" +chao_expert_karate_1 = "Chao Karate - Expert 1" +chao_expert_karate_2 = "Chao Karate - Expert 2" +chao_expert_karate_3 = "Chao Karate - Expert 3" +chao_expert_karate_4 = "Chao Karate - Expert 4" +chao_expert_karate_5 = "Chao Karate - Expert 5" +chao_super_karate_1 = "Chao Karate - Super 1" +chao_super_karate_2 = "Chao Karate - Super 2" +chao_super_karate_3 = "Chao Karate - Super 3" +chao_super_karate_4 = "Chao Karate - Super 4" +chao_super_karate_5 = "Chao Karate - Super 5" + +chao_stat_swim_base = "Chao Stat - Swim - " +chao_stat_fly_base = "Chao Stat - Fly - " +chao_stat_run_base = "Chao Stat - Run - " +chao_stat_power_base = "Chao Stat - Power - " +chao_stat_stamina_base = "Chao Stat - Stamina - " +chao_stat_luck_base = "Chao Stat - Luck - " +chao_stat_intelligence_base = "Chao Stat - Intelligence - " + +chao_black_market_base = "Black Market - " + +# Animal Event Locations +animal_penguin = "Penguin Behavior" +animal_seal = "Seal Behavior" +animal_otter = "Otter Behavior" +animal_rabbit = "Rabbit Behavior" +animal_cheetah = "Cheetah Behavior" +animal_warthog = "Warthog Behavior" +animal_bear = "Bear Behavior" +animal_tiger = "Tiger Behavior" +animal_gorilla = "Gorilla Behavior" +animal_peacock = "Peacock Behavior" +animal_parrot = "Parrot Behavior" +animal_condor = "Condor Behavior" +animal_skunk = "Skunk Behavior" +animal_sheep = "Sheep Behavior" +animal_raccoon = "Raccoon Behavior" +animal_halffish = "HalfFish Behavior" +animal_skeleton_dog = "Skeleton Dog Behavior" +animal_bat = "Bat Behavior" +animal_dragon = "Dragon Behavior" +animal_unicorn = "Unicorn Behavior" +animal_phoenix = "Phoenix Behavior" + +# Animal Body Part Locations +chao_penguin_arms = "Chao - Penguin Arms" +chao_penguin_forehead = "Chao - Penguin Forehead" +chao_penguin_legs = "Chao - Penguin Legs" + +chao_seal_arms = "Chao - Seal Arms" +chao_seal_tail = "Chao - Seal Tail" + +chao_otter_arms = "Chao - Otter Arms" +chao_otter_ears = "Chao - Otter Ears" +chao_otter_face = "Chao - Otter Face" +chao_otter_legs = "Chao - Otter Legs" +chao_otter_tail = "Chao - Otter Tail" + +chao_rabbit_arms = "Chao - Rabbit Arms" +chao_rabbit_ears = "Chao - Rabbit Ears" +chao_rabbit_legs = "Chao - Rabbit Legs" +chao_rabbit_tail = "Chao - Rabbit Tail" + +chao_cheetah_arms = "Chao - Cheetah Arms" +chao_cheetah_ears = "Chao - Cheetah Ears" +chao_cheetah_legs = "Chao - Cheetah Legs" +chao_cheetah_tail = "Chao - Cheetah Tail" + +chao_warthog_arms = "Chao - Warthog Arms" +chao_warthog_ears = "Chao - Warthog Ears" +chao_warthog_face = "Chao - Warthog Face" +chao_warthog_legs = "Chao - Warthog Legs" +chao_warthog_tail = "Chao - Warthog Tail" + +chao_bear_arms = "Chao - Bear Arms" +chao_bear_ears = "Chao - Bear Ears" +chao_bear_legs = "Chao - Bear Legs" + +chao_tiger_arms = "Chao - Tiger Arms" +chao_tiger_ears = "Chao - Tiger Ears" +chao_tiger_legs = "Chao - Tiger Legs" +chao_tiger_tail = "Chao - Tiger Tail" + +chao_gorilla_arms = "Chao - Gorilla Arms" +chao_gorilla_ears = "Chao - Gorilla Ears" +chao_gorilla_forehead = "Chao - Gorilla Forehead" +chao_gorilla_legs = "Chao - Gorilla Legs" + +chao_peacock_forehead = "Chao - Peacock Forehead" +chao_peacock_legs = "Chao - Peacock Legs" +chao_peacock_tail = "Chao - Peacock Tail" +chao_peacock_wings = "Chao - Peacock Wings" + +chao_parrot_forehead = "Chao - Parrot Forehead" +chao_parrot_legs = "Chao - Parrot Legs" +chao_parrot_tail = "Chao - Parrot Tail" +chao_parrot_wings = "Chao - Parrot Wings" + +chao_condor_ears = "Chao - Condor Ears" +chao_condor_legs = "Chao - Condor Legs" +chao_condor_tail = "Chao - Condor Tail" +chao_condor_wings = "Chao - Condor Wings" + +chao_skunk_arms = "Chao - Skunk Arms" +chao_skunk_forehead = "Chao - Skunk Forehead" +chao_skunk_legs = "Chao - Skunk Legs" +chao_skunk_tail = "Chao - Skunk Tail" + +chao_sheep_arms = "Chao - Sheep Arms" +chao_sheep_ears = "Chao - Sheep Ears" +chao_sheep_legs = "Chao - Sheep Legs" +chao_sheep_horn = "Chao - Sheep Horn" +chao_sheep_tail = "Chao - Sheep Tail" + +chao_raccoon_arms = "Chao - Raccoon Arms" +chao_raccoon_ears = "Chao - Raccoon Ears" +chao_raccoon_legs = "Chao - Raccoon Legs" + +chao_dragon_arms = "Chao - Dragon Arms" +chao_dragon_ears = "Chao - Dragon Ears" +chao_dragon_legs = "Chao - Dragon Legs" +chao_dragon_horn = "Chao - Dragon Horn" +chao_dragon_tail = "Chao - Dragon Tail" +chao_dragon_wings = "Chao - Dragon Wings" + +chao_unicorn_arms = "Chao - Unicorn Arms" +chao_unicorn_ears = "Chao - Unicorn Ears" +chao_unicorn_forehead = "Chao - Unicorn Forehead" +chao_unicorn_legs = "Chao - Unicorn Legs" +chao_unicorn_tail = "Chao - Unicorn Tail" + +chao_phoenix_forehead = "Chao - Phoenix Forehead" +chao_phoenix_legs = "Chao - Phoenix Legs" +chao_phoenix_tail = "Chao - Phoenix Tail" +chao_phoenix_wings = "Chao - Phoenix Wings" + +# Chao Kindergarten Locations +chao_kindergarten_drawing_1 = "Chao Kindergarten - Drawing 1" +chao_kindergarten_drawing_2 = "Chao Kindergarten - Drawing 2" +chao_kindergarten_drawing_3 = "Chao Kindergarten - Drawing 3" +chao_kindergarten_drawing_4 = "Chao Kindergarten - Drawing 4" +chao_kindergarten_drawing_5 = "Chao Kindergarten - Drawing 5" + +chao_kindergarten_shake_dance = "Chao Kindergarten - Shake Dance" +chao_kindergarten_spin_dance = "Chao Kindergarten - Spin Dance" +chao_kindergarten_step_dance = "Chao Kindergarten - Step Dance" +chao_kindergarten_gogo_dance = "Chao Kindergarten - Go-Go Dance" +chao_kindergarten_exercise = "Chao Kindergarten - Exercise" + +chao_kindergarten_song_1 = "Chao Kindergarten - Song 1" +chao_kindergarten_song_2 = "Chao Kindergarten - Song 2" +chao_kindergarten_song_3 = "Chao Kindergarten - Song 3" +chao_kindergarten_song_4 = "Chao Kindergarten - Song 4" +chao_kindergarten_song_5 = "Chao Kindergarten - Song 5" + +chao_kindergarten_bell = "Chao Kindergarten - Bell" +chao_kindergarten_castanets = "Chao Kindergarten - Castanets" +chao_kindergarten_cymbals = "Chao Kindergarten - Cymbals" +chao_kindergarten_drum = "Chao Kindergarten - Drum" +chao_kindergarten_flute = "Chao Kindergarten - Flute" +chao_kindergarten_maracas = "Chao Kindergarten - Maracas" +chao_kindergarten_trumpet = "Chao Kindergarten - Trumpet" +chao_kindergarten_tambourine = "Chao Kindergarten - Tambourine" + +chao_kindergarten_any_drawing = "Chao Kindergarten - Any Drawing" +chao_kindergarten_any_dance = "Chao Kindergarten - Any Dance" +chao_kindergarten_any_song = "Chao Kindergarten - Any Song" +chao_kindergarten_any_instrument = "Chao Kindergarten - Any Instrument" + + +# Chao Goal Locations +chaos_chao = "Chaos Chao" +chaos_chao_region = "Chaos Chao" + # Kart Race Definitions kart_race_beginner_sonic = "Kart Race - Beginner - Sonic" @@ -1261,9 +1442,18 @@ green_hill_region = "Green Hill" grand_prix = "Grand Prix" grand_prix_region = "Grand Prix" -chao_garden_beginner_region = "Chao Garden - Beginner" -chao_garden_intermediate_region = "Chao Garden - Intermediate" -chao_garden_expert_region = "Chao Garden - Expert" +chao_race_beginner_region = "Chao Race - Beginner" +chao_race_intermediate_region = "Chao Race - Intermediate" +chao_race_expert_region = "Chao Race - Expert" + +chao_karate_beginner_region = "Chao Karate - Beginner" +chao_karate_intermediate_region = "Chao Karate - Standard" +chao_karate_expert_region = "Chao Karate - Expert" +chao_karate_super_region = "Chao Karate - Super" + +chao_kindergarten_region = "Chao Kindergarten" + +black_market_region = "Black Market" kart_race_beginner_region = "Kart Race - Beginner" kart_race_standard_region = "Kart Race - Intermediate" diff --git a/worlds/sa2b/Options.py b/worlds/sa2b/Options.py index 6bef9def..be001572 100644 --- a/worlds/sa2b/Options.py +++ b/worlds/sa2b/Options.py @@ -13,6 +13,7 @@ class Goal(Choice): 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 + Chaos Chao: Raise a Chaos Chao to win """ display_name = "Goal" option_biolizard = 0 @@ -22,6 +23,7 @@ class Goal(Choice): option_boss_rush = 4 option_cannons_core_boss_rush = 5 option_boss_rush_chaos_emerald_hunt = 6 + option_chaos_chao = 7 default = 0 @classmethod @@ -70,74 +72,81 @@ class BaseTrapWeight(Choice): class OmochaoTrapWeight(BaseTrapWeight): """ - Likelihood of a receiving a trap which spawns several Omochao around the player + Likelihood of receiving a trap which spawns several Omochao around the player """ display_name = "OmoTrap Weight" class TimestopTrapWeight(BaseTrapWeight): """ - Likelihood of a receiving a trap which briefly stops time + Likelihood of receiving a trap which briefly stops time """ display_name = "Chaos Control Trap Weight" class ConfusionTrapWeight(BaseTrapWeight): """ - Likelihood of a receiving a trap which causes the controls to be skewed for a period of time + Likelihood of receiving a trap which causes the controls to be skewed for a period of time """ display_name = "Confusion Trap Weight" class TinyTrapWeight(BaseTrapWeight): """ - Likelihood of a receiving a trap which causes the player to become tiny + Likelihood of receiving a trap which causes the player to become tiny """ display_name = "Tiny Trap Weight" class GravityTrapWeight(BaseTrapWeight): """ - Likelihood of a receiving a trap which increases gravity + Likelihood of receiving a trap which increases gravity """ display_name = "Gravity Trap Weight" class ExpositionTrapWeight(BaseTrapWeight): """ - Likelihood of a receiving a trap which tells you the story + Likelihood of receiving a trap which tells you the story """ display_name = "Exposition Trap Weight" class DarknessTrapWeight(BaseTrapWeight): """ - Likelihood of a receiving a trap which makes the world dark + Likelihood of receiving a trap which makes the world dark """ display_name = "Darkness Trap Weight" class IceTrapWeight(BaseTrapWeight): """ - Likelihood of a receiving a trap which makes the world slippery + Likelihood of 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 + Likelihood of 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 + Likelihood of receiving a trap which makes you watch an unskippable cutscene """ display_name = "Cutscene Trap Weight" +class ReverseTrapWeight(BaseTrapWeight): + """ + Likelihood of receiving a trap which reverses your controls + """ + display_name = "Reverse Trap Weight" + + class PongTrapWeight(BaseTrapWeight): """ Likelihood of receiving a trap which forces you to play a Pong minigame @@ -219,7 +228,7 @@ class Omosanity(Toggle): class Animalsanity(Toggle): """ Determines whether picking up counted small animals grants checks - (420 Locations) + (421 Locations) """ display_name = "Animalsanity" @@ -291,7 +300,7 @@ class MaximumEmblemCap(Range): """ display_name = "Max Emblem Cap" range_start = 50 - range_end = 500 + range_end = 1000 default = 180 @@ -308,15 +317,15 @@ class RequiredRank(Choice): default = 0 -class ChaoGardenDifficulty(Choice): +class ChaoRaceDifficulty(Choice): """ - Determines the number of chao garden difficulty levels included. Easier difficulty settings means fewer chao garden checks - None: No Chao Garden Activities have checks + Determines the number of Chao Race difficulty levels included. Easier difficulty settings means fewer Chao Race checks + None: No Chao Races have checks Beginner: Beginner Races Intermediate: Beginner, Challenge, Hero, and Dark Races Expert: Beginner, Challenge, Hero, Dark and Jewel Races """ - display_name = "Chao Garden Difficulty" + display_name = "Chao Race Difficulty" option_none = 0 option_beginner = 1 option_intermediate = 2 @@ -324,26 +333,138 @@ class ChaoGardenDifficulty(Choice): default = 0 -class IncludeChaoKarate(Toggle): +class ChaoKarateDifficulty(Choice): """ - Determines whether the Chao Karate should be included as checks (Note: This setting requires purchase of the "Battle" DLC) + Determines the number of Chao Karate difficulty levels included. (Note: This setting requires purchase of the "Battle" DLC) """ - display_name = "Include Chao Karate" + display_name = "Chao Karate Difficulty" + option_none = 0 + option_beginner = 1 + option_standard = 2 + option_expert = 3 + option_super = 4 + default = 0 -class ChaoRaceChecks(Choice): +class ChaoStadiumChecks(Choice): """ - Determines which Chao Races grant checks - All: Each individual race grants a check + Determines which Chao Stadium activities grant checks + All: Each individual race and karate fight grants a check Prize: Only the races which grant Chao Toys grant checks (final race of each Beginner and Jewel cup, 4th, 8th, and - 12th Challenge Races, 2nd and 4th Hero and Dark Races) + 12th Challenge Races, 2nd and 4th Hero and Dark Races, final fight of each Karate difficulty) """ - display_name = "Chao Race Checks" + display_name = "Chao Stadium Checks" option_all = 0 option_prize = 1 default = 0 +class ChaoStats(Range): + """ + Determines the highest level in each Chao Stat that grants checks + (Swim, Fly, Run, Power) + """ + display_name = "Chao Stats" + range_start = 0 + range_end = 99 + default = 0 + + +class ChaoStatsFrequency(Range): + """ + Determines how many levels in each Chao Stat grant checks (up to the maximum set in the `chao_stats` option) + `1` means every level is included, `2` means every other level is included, `3` means every third, and so on + """ + display_name = "Chao Stats Frequency" + range_start = 1 + range_end = 20 + default = 5 + + +class ChaoStatsStamina(Toggle): + """ + Determines whether Stamina is included in the `chao_stats` option + """ + display_name = "Chao Stats - Stamina" + + +class ChaoStatsHidden(Toggle): + """ + Determines whether the hidden stats (Luck and Intelligence) are included in the `chao_stats` option + """ + display_name = "Chao Stats - Luck and Intelligence" + + +class ChaoAnimalParts(Toggle): + """ + Determines whether giving Chao various animal parts grants checks + (73 Locations) + """ + display_name = "Chao Animal Parts" + + +class ChaoKindergarten(Choice): + """ + Determines whether learning the lessons from the Kindergarten Classroom grants checks + (WARNING: VERY SLOW) + None: No Kindergarten classes have checks + Basics: One class from each category (Drawing, Dance, Song, and Instrument) is a check (4 Locations) + Full: Every class is a check (23 Locations) + """ + display_name = "Chao Kindergarten Checks" + option_none = 0 + option_basics = 1 + option_full = 2 + default = 0 + + +class BlackMarketSlots(Range): + """ + Determines how many multiworld items are available to purchase from the Black Market + """ + display_name = "Black Market Slots" + range_start = 0 + range_end = 64 + default = 0 + + +class BlackMarketUnlockCosts(Choice): + """ + Determines how many Chao Coins are required to unlock sets of Black Market items + """ + display_name = "Black Market Unlock Costs" + option_low = 0 + option_medium = 1 + option_high = 2 + default = 1 + + +class BlackMarketPriceMultiplier(Range): + """ + Determines how many rings the Black Market items cost + The base ring costs of items in the Black Market range from 50-100, + and are then multiplied by this value + """ + display_name = "Black Market Price Multiplier" + range_start = 0 + range_end = 40 + default = 1 + + +class ShuffleStartingChaoEggs(DefaultOnToggle): + """ + Determines whether the starting Chao eggs in the gardens are random + """ + display_name = "Shuffle Starting Chao Eggs" + + +class ChaoEntranceRandomization(Toggle): + """ + Determines whether entrances in Chao World are randomized + """ + display_name = "Chao Entrance Randomization" + + class RequiredCannonsCoreMissions(Choice): """ Determines how many Cannon's Core missions must be completed (for Biolizard or Cannon's Core goals) @@ -657,24 +778,42 @@ class LogicDifficulty(Choice): sa2b_options: typing.Dict[str, type(Option)] = { "goal": Goal, + "mission_shuffle": MissionShuffle, "boss_rush_shuffle": BossRushShuffle, + "keysanity": Keysanity, "whistlesanity": Whistlesanity, "beetlesanity": Beetlesanity, "omosanity": Omosanity, "animalsanity": Animalsanity, "kart_race_checks": KartRaceChecks, + + "logic_difficulty": LogicDifficulty, "required_rank": RequiredRank, - "emblem_percentage_for_cannons_core": EmblemPercentageForCannonsCore, "required_cannons_core_missions": RequiredCannonsCoreMissions, + + "emblem_percentage_for_cannons_core": EmblemPercentageForCannonsCore, "number_of_level_gates": NumberOfLevelGates, "level_gate_distribution": LevelGateDistribution, "level_gate_costs": LevelGateCosts, "max_emblem_cap": MaximumEmblemCap, - "chao_garden_difficulty": ChaoGardenDifficulty, - "include_chao_karate": IncludeChaoKarate, - "chao_race_checks": ChaoRaceChecks, + + "chao_race_difficulty": ChaoRaceDifficulty, + "chao_karate_difficulty": ChaoKarateDifficulty, + "chao_stadium_checks": ChaoStadiumChecks, + "chao_stats": ChaoStats, + "chao_stats_frequency": ChaoStatsFrequency, + "chao_stats_stamina": ChaoStatsStamina, + "chao_stats_hidden": ChaoStatsHidden, + "chao_animal_parts": ChaoAnimalParts, + "chao_kindergarten": ChaoKindergarten, + "black_market_slots": BlackMarketSlots, + "black_market_unlock_costs": BlackMarketUnlockCosts, + "black_market_price_multiplier": BlackMarketPriceMultiplier, + "shuffle_starting_chao_eggs": ShuffleStartingChaoEggs, + "chao_entrance_randomization": ChaoEntranceRandomization, + "junk_fill_percentage": JunkFillPercentage, "trap_fill_percentage": TrapFillPercentage, "omochao_trap_weight": OmochaoTrapWeight, @@ -687,39 +826,46 @@ sa2b_options: typing.Dict[str, type(Option)] = { "ice_trap_weight": IceTrapWeight, "slow_trap_weight": SlowTrapWeight, "cutscene_trap_weight": CutsceneTrapWeight, + "reverse_trap_weight": ReverseTrapWeight, "pong_trap_weight": PongTrapWeight, "minigame_trap_difficulty": MinigameTrapDifficulty, - "ring_loss": RingLoss, - "ring_link": RingLink, + "sadx_music": SADXMusic, "music_shuffle": MusicShuffle, "voice_shuffle": VoiceShuffle, "narrator": Narrator, - "logic_difficulty": LogicDifficulty, + "ring_loss": RingLoss, + "speed_mission_count": SpeedMissionCount, "speed_mission_2": SpeedMission2, "speed_mission_3": SpeedMission3, "speed_mission_4": SpeedMission4, "speed_mission_5": SpeedMission5, + "mech_mission_count": MechMissionCount, "mech_mission_2": MechMission2, "mech_mission_3": MechMission3, "mech_mission_4": MechMission4, "mech_mission_5": MechMission5, + "hunt_mission_count": HuntMissionCount, "hunt_mission_2": HuntMission2, "hunt_mission_3": HuntMission3, "hunt_mission_4": HuntMission4, "hunt_mission_5": HuntMission5, + "kart_mission_count": KartMissionCount, "kart_mission_2": KartMission2, "kart_mission_3": KartMission3, "kart_mission_4": KartMission4, "kart_mission_5": KartMission5, + "cannons_core_mission_count": CannonsCoreMissionCount, "cannons_core_mission_2": CannonsCoreMission2, "cannons_core_mission_3": CannonsCoreMission3, "cannons_core_mission_4": CannonsCoreMission4, "cannons_core_mission_5": CannonsCoreMission5, + + "ring_link": RingLink, "death_link": DeathLink, } diff --git a/worlds/sa2b/Regions.py b/worlds/sa2b/Regions.py index da519283..fb6472d6 100644 --- a/worlds/sa2b/Regions.py +++ b/worlds/sa2b/Regions.py @@ -1,8 +1,14 @@ import typing +import math -from BaseClasses import MultiWorld, Region, Entrance +from BaseClasses import MultiWorld, Region, Entrance, ItemClassification +from worlds.AutoWorld import World from .Items import SA2BItem -from .Locations import SA2BLocation, boss_gate_location_table, boss_gate_set +from .Locations import SA2BLocation, boss_gate_location_table, boss_gate_set,\ + chao_stat_swim_table, chao_stat_fly_table, chao_stat_run_table,\ + chao_stat_power_table, chao_stat_stamina_table,\ + chao_stat_luck_table, chao_stat_intelligence_table, chao_animal_event_location_table,\ + chao_kindergarten_location_table, chao_kindergarten_basics_location_table, black_market_location_table from .Names import LocationName, ItemName from .GateBosses import get_boss_name, all_gate_bosses_table, king_boom_boo @@ -86,35 +92,37 @@ gate_0_whitelist_regions = [ ] -def create_regions(world, player: int, active_locations): - menu_region = create_region(world, player, active_locations, 'Menu', None) +def create_regions(multiworld: MultiWorld, world: World, player: int, active_locations): + menu_region = create_region(multiworld, player, active_locations, 'Menu', None) - gate_0_region = create_region(world, player, active_locations, 'Gate 0', None) + conditional_regions = [] + gate_0_region = create_region(multiworld, player, active_locations, 'Gate 0', None) + conditional_regions += [gate_0_region] - if world.number_of_level_gates[player].value >= 1: - gate_1_boss_region = create_region(world, player, active_locations, 'Gate 1 Boss', [LocationName.gate_1_boss]) - gate_1_region = create_region(world, player, active_locations, 'Gate 1', None) - world.regions += [gate_1_region, gate_1_boss_region] + if world.options.number_of_level_gates.value >= 1: + gate_1_boss_region = create_region(multiworld, player, active_locations, 'Gate 1 Boss', [LocationName.gate_1_boss]) + gate_1_region = create_region(multiworld, player, active_locations, 'Gate 1', None) + conditional_regions += [gate_1_region, gate_1_boss_region] - if world.number_of_level_gates[player].value >= 2: - gate_2_boss_region = create_region(world, player, active_locations, 'Gate 2 Boss', [LocationName.gate_2_boss]) - gate_2_region = create_region(world, player, active_locations, 'Gate 2', None) - world.regions += [gate_2_region, gate_2_boss_region] + if world.options.number_of_level_gates.value >= 2: + gate_2_boss_region = create_region(multiworld, player, active_locations, 'Gate 2 Boss', [LocationName.gate_2_boss]) + gate_2_region = create_region(multiworld, player, active_locations, 'Gate 2', None) + conditional_regions += [gate_2_region, gate_2_boss_region] - if world.number_of_level_gates[player].value >= 3: - gate_3_boss_region = create_region(world, player, active_locations, 'Gate 3 Boss', [LocationName.gate_3_boss]) - gate_3_region = create_region(world, player, active_locations, 'Gate 3', None) - world.regions += [gate_3_region, gate_3_boss_region] + if world.options.number_of_level_gates.value >= 3: + gate_3_boss_region = create_region(multiworld, player, active_locations, 'Gate 3 Boss', [LocationName.gate_3_boss]) + gate_3_region = create_region(multiworld, player, active_locations, 'Gate 3', None) + conditional_regions += [gate_3_region, gate_3_boss_region] - if world.number_of_level_gates[player].value >= 4: - gate_4_boss_region = create_region(world, player, active_locations, 'Gate 4 Boss', [LocationName.gate_4_boss]) - gate_4_region = create_region(world, player, active_locations, 'Gate 4', None) - world.regions += [gate_4_region, gate_4_boss_region] + if world.options.number_of_level_gates.value >= 4: + gate_4_boss_region = create_region(multiworld, player, active_locations, 'Gate 4 Boss', [LocationName.gate_4_boss]) + gate_4_region = create_region(multiworld, player, active_locations, 'Gate 4', None) + conditional_regions += [gate_4_region, gate_4_boss_region] - if world.number_of_level_gates[player].value >= 5: - gate_5_boss_region = create_region(world, player, active_locations, 'Gate 5 Boss', [LocationName.gate_5_boss]) - gate_5_region = create_region(world, player, active_locations, 'Gate 5', None) - world.regions += [gate_5_region, gate_5_boss_region] + if world.options.number_of_level_gates.value >= 5: + gate_5_boss_region = create_region(multiworld, player, active_locations, 'Gate 5 Boss', [LocationName.gate_5_boss]) + gate_5_region = create_region(multiworld, player, active_locations, 'Gate 5', None) + conditional_regions += [gate_5_region, gate_5_boss_region] city_escape_region_locations = [ LocationName.city_escape_1, @@ -171,7 +179,7 @@ def create_regions(world, player: int, active_locations): LocationName.city_escape_animal_20, LocationName.city_escape_upgrade, ] - city_escape_region = create_region(world, player, active_locations, LocationName.city_escape_region, + city_escape_region = create_region(multiworld, player, active_locations, LocationName.city_escape_region, city_escape_region_locations) metal_harbor_region_locations = [ @@ -206,7 +214,7 @@ def create_regions(world, player: int, active_locations): LocationName.metal_harbor_animal_14, LocationName.metal_harbor_upgrade, ] - metal_harbor_region = create_region(world, player, active_locations, LocationName.metal_harbor_region, + metal_harbor_region = create_region(multiworld, player, active_locations, LocationName.metal_harbor_region, metal_harbor_region_locations) green_forest_region_locations = [ @@ -245,7 +253,7 @@ def create_regions(world, player: int, active_locations): LocationName.green_forest_animal_18, LocationName.green_forest_upgrade, ] - green_forest_region = create_region(world, player, active_locations, LocationName.green_forest_region, + green_forest_region = create_region(multiworld, player, active_locations, LocationName.green_forest_region, green_forest_region_locations) pyramid_cave_region_locations = [ @@ -287,7 +295,7 @@ def create_regions(world, player: int, active_locations): LocationName.pyramid_cave_animal_19, LocationName.pyramid_cave_upgrade, ] - pyramid_cave_region = create_region(world, player, active_locations, LocationName.pyramid_cave_region, + pyramid_cave_region = create_region(multiworld, player, active_locations, LocationName.pyramid_cave_region, pyramid_cave_region_locations) crazy_gadget_region_locations = [ @@ -336,7 +344,7 @@ def create_regions(world, player: int, active_locations): LocationName.crazy_gadget_animal_16, LocationName.crazy_gadget_upgrade, ] - crazy_gadget_region = create_region(world, player, active_locations, LocationName.crazy_gadget_region, + crazy_gadget_region = create_region(multiworld, player, active_locations, LocationName.crazy_gadget_region, crazy_gadget_region_locations) final_rush_region_locations = [ @@ -372,7 +380,7 @@ def create_regions(world, player: int, active_locations): LocationName.final_rush_animal_16, LocationName.final_rush_upgrade, ] - final_rush_region = create_region(world, player, active_locations, LocationName.final_rush_region, + final_rush_region = create_region(multiworld, player, active_locations, LocationName.final_rush_region, final_rush_region_locations) prison_lane_region_locations = [ @@ -418,7 +426,7 @@ def create_regions(world, player: int, active_locations): LocationName.prison_lane_animal_15, LocationName.prison_lane_upgrade, ] - prison_lane_region = create_region(world, player, active_locations, LocationName.prison_lane_region, + prison_lane_region = create_region(multiworld, player, active_locations, LocationName.prison_lane_region, prison_lane_region_locations) mission_street_region_locations = [ @@ -464,7 +472,7 @@ def create_regions(world, player: int, active_locations): LocationName.mission_street_animal_16, LocationName.mission_street_upgrade, ] - mission_street_region = create_region(world, player, active_locations, LocationName.mission_street_region, + mission_street_region = create_region(multiworld, player, active_locations, LocationName.mission_street_region, mission_street_region_locations) route_101_region_locations = [ @@ -474,7 +482,7 @@ def create_regions(world, player: int, active_locations): LocationName.route_101_4, LocationName.route_101_5, ] - route_101_region = create_region(world, player, active_locations, LocationName.route_101_region, + route_101_region = create_region(multiworld, player, active_locations, LocationName.route_101_region, route_101_region_locations) hidden_base_region_locations = [ @@ -512,7 +520,7 @@ def create_regions(world, player: int, active_locations): LocationName.hidden_base_animal_15, LocationName.hidden_base_upgrade, ] - hidden_base_region = create_region(world, player, active_locations, LocationName.hidden_base_region, + hidden_base_region = create_region(multiworld, player, active_locations, LocationName.hidden_base_region, hidden_base_region_locations) eternal_engine_region_locations = [ @@ -559,7 +567,7 @@ def create_regions(world, player: int, active_locations): LocationName.eternal_engine_animal_15, LocationName.eternal_engine_upgrade, ] - eternal_engine_region = create_region(world, player, active_locations, LocationName.eternal_engine_region, + eternal_engine_region = create_region(multiworld, player, active_locations, LocationName.eternal_engine_region, eternal_engine_region_locations) wild_canyon_region_locations = [ @@ -597,7 +605,7 @@ def create_regions(world, player: int, active_locations): LocationName.wild_canyon_animal_10, LocationName.wild_canyon_upgrade, ] - wild_canyon_region = create_region(world, player, active_locations, LocationName.wild_canyon_region, + wild_canyon_region = create_region(multiworld, player, active_locations, LocationName.wild_canyon_region, wild_canyon_region_locations) pumpkin_hill_region_locations = [ @@ -635,7 +643,7 @@ def create_regions(world, player: int, active_locations): LocationName.pumpkin_hill_animal_11, LocationName.pumpkin_hill_upgrade, ] - pumpkin_hill_region = create_region(world, player, active_locations, LocationName.pumpkin_hill_region, + pumpkin_hill_region = create_region(multiworld, player, active_locations, LocationName.pumpkin_hill_region, pumpkin_hill_region_locations) aquatic_mine_region_locations = [ @@ -670,7 +678,7 @@ def create_regions(world, player: int, active_locations): LocationName.aquatic_mine_animal_10, LocationName.aquatic_mine_upgrade, ] - aquatic_mine_region = create_region(world, player, active_locations, LocationName.aquatic_mine_region, + aquatic_mine_region = create_region(multiworld, player, active_locations, LocationName.aquatic_mine_region, aquatic_mine_region_locations) death_chamber_region_locations = [ @@ -709,7 +717,7 @@ def create_regions(world, player: int, active_locations): LocationName.death_chamber_animal_10, LocationName.death_chamber_upgrade, ] - death_chamber_region = create_region(world, player, active_locations, LocationName.death_chamber_region, + death_chamber_region = create_region(multiworld, player, active_locations, LocationName.death_chamber_region, death_chamber_region_locations) meteor_herd_region_locations = [ @@ -741,7 +749,7 @@ def create_regions(world, player: int, active_locations): LocationName.meteor_herd_animal_11, LocationName.meteor_herd_upgrade, ] - meteor_herd_region = create_region(world, player, active_locations, LocationName.meteor_herd_region, + meteor_herd_region = create_region(multiworld, player, active_locations, LocationName.meteor_herd_region, meteor_herd_region_locations) radical_highway_region_locations = [ @@ -790,7 +798,7 @@ def create_regions(world, player: int, active_locations): LocationName.radical_highway_animal_20, LocationName.radical_highway_upgrade, ] - radical_highway_region = create_region(world, player, active_locations, LocationName.radical_highway_region, + radical_highway_region = create_region(multiworld, player, active_locations, LocationName.radical_highway_region, radical_highway_region_locations) white_jungle_region_locations = [ @@ -833,7 +841,7 @@ def create_regions(world, player: int, active_locations): LocationName.white_jungle_animal_16, LocationName.white_jungle_upgrade, ] - white_jungle_region = create_region(world, player, active_locations, LocationName.white_jungle_region, + white_jungle_region = create_region(multiworld, player, active_locations, LocationName.white_jungle_region, white_jungle_region_locations) sky_rail_region_locations = [ @@ -874,7 +882,7 @@ def create_regions(world, player: int, active_locations): LocationName.sky_rail_animal_20, LocationName.sky_rail_upgrade, ] - sky_rail_region = create_region(world, player, active_locations, LocationName.sky_rail_region, + sky_rail_region = create_region(multiworld, player, active_locations, LocationName.sky_rail_region, sky_rail_region_locations) final_chase_region_locations = [ @@ -910,7 +918,7 @@ def create_regions(world, player: int, active_locations): LocationName.final_chase_animal_17, LocationName.final_chase_upgrade, ] - final_chase_region = create_region(world, player, active_locations, LocationName.final_chase_region, + final_chase_region = create_region(multiworld, player, active_locations, LocationName.final_chase_region, final_chase_region_locations) iron_gate_region_locations = [ @@ -951,7 +959,7 @@ def create_regions(world, player: int, active_locations): LocationName.iron_gate_animal_15, LocationName.iron_gate_upgrade, ] - iron_gate_region = create_region(world, player, active_locations, LocationName.iron_gate_region, + iron_gate_region = create_region(multiworld, player, active_locations, LocationName.iron_gate_region, iron_gate_region_locations) sand_ocean_region_locations = [ @@ -988,7 +996,7 @@ def create_regions(world, player: int, active_locations): LocationName.sand_ocean_animal_15, LocationName.sand_ocean_upgrade, ] - sand_ocean_region = create_region(world, player, active_locations, LocationName.sand_ocean_region, + sand_ocean_region = create_region(multiworld, player, active_locations, LocationName.sand_ocean_region, sand_ocean_region_locations) lost_colony_region_locations = [ @@ -1028,7 +1036,7 @@ def create_regions(world, player: int, active_locations): LocationName.lost_colony_animal_14, LocationName.lost_colony_upgrade, ] - lost_colony_region = create_region(world, player, active_locations, LocationName.lost_colony_region, + lost_colony_region = create_region(multiworld, player, active_locations, LocationName.lost_colony_region, lost_colony_region_locations) weapons_bed_region_locations = [ @@ -1065,7 +1073,7 @@ def create_regions(world, player: int, active_locations): LocationName.weapons_bed_animal_15, LocationName.weapons_bed_upgrade, ] - weapons_bed_region = create_region(world, player, active_locations, LocationName.weapons_bed_region, + weapons_bed_region = create_region(multiworld, player, active_locations, LocationName.weapons_bed_region, weapons_bed_region_locations) cosmic_wall_region_locations = [ @@ -1101,7 +1109,7 @@ def create_regions(world, player: int, active_locations): LocationName.cosmic_wall_animal_15, LocationName.cosmic_wall_upgrade, ] - cosmic_wall_region = create_region(world, player, active_locations, LocationName.cosmic_wall_region, + cosmic_wall_region = create_region(multiworld, player, active_locations, LocationName.cosmic_wall_region, cosmic_wall_region_locations) dry_lagoon_region_locations = [ @@ -1138,9 +1146,10 @@ def create_regions(world, player: int, active_locations): LocationName.dry_lagoon_animal_8, LocationName.dry_lagoon_animal_9, LocationName.dry_lagoon_animal_10, + LocationName.dry_lagoon_animal_11, LocationName.dry_lagoon_upgrade, ] - dry_lagoon_region = create_region(world, player, active_locations, LocationName.dry_lagoon_region, + dry_lagoon_region = create_region(multiworld, player, active_locations, LocationName.dry_lagoon_region, dry_lagoon_region_locations) egg_quarters_region_locations = [ @@ -1176,7 +1185,7 @@ def create_regions(world, player: int, active_locations): LocationName.egg_quarters_animal_10, LocationName.egg_quarters_upgrade, ] - egg_quarters_region = create_region(world, player, active_locations, LocationName.egg_quarters_region, + egg_quarters_region = create_region(multiworld, player, active_locations, LocationName.egg_quarters_region, egg_quarters_region_locations) security_hall_region_locations = [ @@ -1213,7 +1222,7 @@ def create_regions(world, player: int, active_locations): LocationName.security_hall_animal_8, LocationName.security_hall_upgrade, ] - security_hall_region = create_region(world, player, active_locations, LocationName.security_hall_region, + security_hall_region = create_region(multiworld, player, active_locations, LocationName.security_hall_region, security_hall_region_locations) route_280_region_locations = [ @@ -1223,7 +1232,7 @@ def create_regions(world, player: int, active_locations): LocationName.route_280_4, LocationName.route_280_5, ] - route_280_region = create_region(world, player, active_locations, LocationName.route_280_region, + route_280_region = create_region(multiworld, player, active_locations, LocationName.route_280_region, route_280_region_locations) mad_space_region_locations = [ @@ -1257,7 +1266,7 @@ def create_regions(world, player: int, active_locations): LocationName.mad_space_animal_10, LocationName.mad_space_upgrade, ] - mad_space_region = create_region(world, player, active_locations, LocationName.mad_space_region, + mad_space_region = create_region(multiworld, player, active_locations, LocationName.mad_space_region, mad_space_region_locations) cannon_core_region_locations = [ @@ -1305,10 +1314,10 @@ def create_regions(world, player: int, active_locations): LocationName.cannon_core_animal_19, LocationName.cannon_core_beetle, ] - cannon_core_region = create_region(world, player, active_locations, LocationName.cannon_core_region, + cannon_core_region = create_region(multiworld, player, active_locations, LocationName.cannon_core_region, cannon_core_region_locations) - chao_garden_beginner_region_locations = [ + chao_race_beginner_region_locations = [ LocationName.chao_race_crab_pool_1, LocationName.chao_race_crab_pool_2, LocationName.chao_race_crab_pool_3, @@ -1321,13 +1330,21 @@ def create_regions(world, player: int, active_locations): LocationName.chao_race_block_canyon_1, LocationName.chao_race_block_canyon_2, LocationName.chao_race_block_canyon_3, - - LocationName.chao_beginner_karate, ] - chao_garden_beginner_region = create_region(world, player, active_locations, LocationName.chao_garden_beginner_region, - chao_garden_beginner_region_locations) + chao_race_beginner_region = create_region(multiworld, player, active_locations, LocationName.chao_race_beginner_region, + chao_race_beginner_region_locations) - chao_garden_intermediate_region_locations = [ + chao_karate_beginner_region_locations = [ + LocationName.chao_beginner_karate_1, + LocationName.chao_beginner_karate_2, + LocationName.chao_beginner_karate_3, + LocationName.chao_beginner_karate_4, + LocationName.chao_beginner_karate_5, + ] + chao_karate_beginner_region = create_region(multiworld, player, active_locations, LocationName.chao_karate_beginner_region, + chao_karate_beginner_region_locations) + + chao_race_intermediate_region_locations = [ LocationName.chao_race_challenge_1, LocationName.chao_race_challenge_2, LocationName.chao_race_challenge_3, @@ -1350,13 +1367,21 @@ def create_regions(world, player: int, active_locations): LocationName.chao_race_dark_2, LocationName.chao_race_dark_3, LocationName.chao_race_dark_4, - - LocationName.chao_standard_karate, ] - chao_garden_intermediate_region = create_region(world, player, active_locations, LocationName.chao_garden_intermediate_region, - chao_garden_intermediate_region_locations) + chao_race_intermediate_region = create_region(multiworld, player, active_locations, LocationName.chao_race_intermediate_region, + chao_race_intermediate_region_locations) - chao_garden_expert_region_locations = [ + chao_karate_intermediate_region_locations = [ + LocationName.chao_standard_karate_1, + LocationName.chao_standard_karate_2, + LocationName.chao_standard_karate_3, + LocationName.chao_standard_karate_4, + LocationName.chao_standard_karate_5, + ] + chao_karate_intermediate_region = create_region(multiworld, player, active_locations, LocationName.chao_karate_intermediate_region, + chao_karate_intermediate_region_locations) + + chao_race_expert_region_locations = [ LocationName.chao_race_aquamarine_1, LocationName.chao_race_aquamarine_2, LocationName.chao_race_aquamarine_3, @@ -1387,15 +1412,266 @@ def create_regions(world, player: int, active_locations): LocationName.chao_race_diamond_3, LocationName.chao_race_diamond_4, LocationName.chao_race_diamond_5, - - LocationName.chao_expert_karate, - LocationName.chao_super_karate, ] - chao_garden_expert_region = create_region(world, player, active_locations, LocationName.chao_garden_expert_region, - chao_garden_expert_region_locations) + chao_race_expert_region = create_region(multiworld, player, active_locations, LocationName.chao_race_expert_region, + chao_race_expert_region_locations) + + chao_karate_expert_region_locations = [ + LocationName.chao_expert_karate_1, + LocationName.chao_expert_karate_2, + LocationName.chao_expert_karate_3, + LocationName.chao_expert_karate_4, + LocationName.chao_expert_karate_5, + ] + chao_karate_expert_region = create_region(multiworld, player, active_locations, LocationName.chao_karate_expert_region, + chao_karate_expert_region_locations) + + chao_karate_super_region_locations = [ + LocationName.chao_super_karate_1, + LocationName.chao_super_karate_2, + LocationName.chao_super_karate_3, + LocationName.chao_super_karate_4, + LocationName.chao_super_karate_5, + ] + chao_karate_super_region = create_region(multiworld, player, active_locations, LocationName.chao_karate_super_region, + chao_karate_super_region_locations) + + if world.options.goal == 7 or world.options.chao_animal_parts: + animal_penguin_region_locations = [ + LocationName.animal_penguin, + LocationName.chao_penguin_arms, + LocationName.chao_penguin_forehead, + LocationName.chao_penguin_legs, + ] + animal_penguin_region = create_region(multiworld, player, active_locations, LocationName.animal_penguin, + animal_penguin_region_locations) + conditional_regions += [animal_penguin_region] + + animal_seal_region_locations = [ + LocationName.animal_seal, + LocationName.chao_seal_arms, + LocationName.chao_seal_tail, + ] + animal_seal_region = create_region(multiworld, player, active_locations, LocationName.animal_seal, + animal_seal_region_locations) + conditional_regions += [animal_seal_region] + + animal_otter_region_locations = [ + LocationName.animal_otter, + LocationName.chao_otter_arms, + LocationName.chao_otter_ears, + LocationName.chao_otter_face, + LocationName.chao_otter_legs, + LocationName.chao_otter_tail, + ] + animal_otter_region = create_region(multiworld, player, active_locations, LocationName.animal_otter, + animal_otter_region_locations) + conditional_regions += [animal_otter_region] + + animal_rabbit_region_locations = [ + LocationName.animal_rabbit, + LocationName.chao_rabbit_arms, + LocationName.chao_rabbit_ears, + LocationName.chao_rabbit_legs, + LocationName.chao_rabbit_tail, + ] + animal_rabbit_region = create_region(multiworld, player, active_locations, LocationName.animal_rabbit, + animal_rabbit_region_locations) + conditional_regions += [animal_rabbit_region] + + animal_cheetah_region_locations = [ + LocationName.animal_cheetah, + LocationName.chao_cheetah_arms, + LocationName.chao_cheetah_ears, + LocationName.chao_cheetah_legs, + LocationName.chao_cheetah_tail, + ] + animal_cheetah_region = create_region(multiworld, player, active_locations, LocationName.animal_cheetah, + animal_cheetah_region_locations) + conditional_regions += [animal_cheetah_region] + + animal_warthog_region_locations = [ + LocationName.animal_warthog, + LocationName.chao_warthog_arms, + LocationName.chao_warthog_ears, + LocationName.chao_warthog_face, + LocationName.chao_warthog_legs, + LocationName.chao_warthog_tail, + ] + animal_warthog_region = create_region(multiworld, player, active_locations, LocationName.animal_warthog, + animal_warthog_region_locations) + conditional_regions += [animal_warthog_region] + + animal_bear_region_locations = [ + LocationName.animal_bear, + LocationName.chao_bear_arms, + LocationName.chao_bear_ears, + LocationName.chao_bear_legs, + ] + animal_bear_region = create_region(multiworld, player, active_locations, LocationName.animal_bear, + animal_bear_region_locations) + conditional_regions += [animal_bear_region] + + animal_tiger_region_locations = [ + LocationName.animal_tiger, + LocationName.chao_tiger_arms, + LocationName.chao_tiger_ears, + LocationName.chao_tiger_legs, + LocationName.chao_tiger_tail, + ] + animal_tiger_region = create_region(multiworld, player, active_locations, LocationName.animal_tiger, + animal_tiger_region_locations) + conditional_regions += [animal_tiger_region] + + animal_gorilla_region_locations = [ + LocationName.animal_gorilla, + LocationName.chao_gorilla_arms, + LocationName.chao_gorilla_ears, + LocationName.chao_gorilla_forehead, + LocationName.chao_gorilla_legs, + ] + animal_gorilla_region = create_region(multiworld, player, active_locations, LocationName.animal_gorilla, + animal_gorilla_region_locations) + conditional_regions += [animal_gorilla_region] + + animal_peacock_region_locations = [ + LocationName.animal_peacock, + LocationName.chao_peacock_forehead, + LocationName.chao_peacock_legs, + LocationName.chao_peacock_tail, + LocationName.chao_peacock_wings, + ] + animal_peacock_region = create_region(multiworld, player, active_locations, LocationName.animal_peacock, + animal_peacock_region_locations) + conditional_regions += [animal_peacock_region] + + animal_parrot_region_locations = [ + LocationName.animal_parrot, + LocationName.chao_parrot_forehead, + LocationName.chao_parrot_legs, + LocationName.chao_parrot_tail, + LocationName.chao_parrot_wings, + ] + animal_parrot_region = create_region(multiworld, player, active_locations, LocationName.animal_parrot, + animal_parrot_region_locations) + conditional_regions += [animal_parrot_region] + + animal_condor_region_locations = [ + LocationName.animal_condor, + LocationName.chao_condor_ears, + LocationName.chao_condor_legs, + LocationName.chao_condor_tail, + LocationName.chao_condor_wings, + ] + animal_condor_region = create_region(multiworld, player, active_locations, LocationName.animal_condor, + animal_condor_region_locations) + conditional_regions += [animal_condor_region] + + animal_skunk_region_locations = [ + LocationName.animal_skunk, + LocationName.chao_skunk_arms, + LocationName.chao_skunk_forehead, + LocationName.chao_skunk_legs, + LocationName.chao_skunk_tail, + ] + animal_skunk_region = create_region(multiworld, player, active_locations, LocationName.animal_skunk, + animal_skunk_region_locations) + conditional_regions += [animal_skunk_region] + + animal_sheep_region_locations = [ + LocationName.animal_sheep, + LocationName.chao_sheep_arms, + LocationName.chao_sheep_ears, + LocationName.chao_sheep_legs, + LocationName.chao_sheep_horn, + LocationName.chao_sheep_tail, + ] + animal_sheep_region = create_region(multiworld, player, active_locations, LocationName.animal_sheep, + animal_sheep_region_locations) + conditional_regions += [animal_sheep_region] + + animal_raccoon_region_locations = [ + LocationName.animal_raccoon, + LocationName.chao_raccoon_arms, + LocationName.chao_raccoon_ears, + LocationName.chao_raccoon_legs, + ] + animal_raccoon_region = create_region(multiworld, player, active_locations, LocationName.animal_raccoon, + animal_raccoon_region_locations) + conditional_regions += [animal_raccoon_region] + + animal_halffish_region_locations = [ + LocationName.animal_halffish, + ] + animal_halffish_region = create_region(multiworld, player, active_locations, LocationName.animal_halffish, + animal_halffish_region_locations) + conditional_regions += [animal_halffish_region] + + animal_skeleton_dog_region_locations = [ + LocationName.animal_skeleton_dog, + ] + animal_skeleton_dog_region = create_region(multiworld, player, active_locations, LocationName.animal_skeleton_dog, + animal_skeleton_dog_region_locations) + conditional_regions += [animal_skeleton_dog_region] + + animal_bat_region_locations = [ + LocationName.animal_bat, + ] + animal_bat_region = create_region(multiworld, player, active_locations, LocationName.animal_bat, + animal_bat_region_locations) + conditional_regions += [animal_bat_region] + + animal_dragon_region_locations = [ + LocationName.animal_dragon, + LocationName.chao_dragon_arms, + LocationName.chao_dragon_ears, + LocationName.chao_dragon_legs, + LocationName.chao_dragon_horn, + LocationName.chao_dragon_tail, + LocationName.chao_dragon_wings, + ] + animal_dragon_region = create_region(multiworld, player, active_locations, LocationName.animal_dragon, + animal_dragon_region_locations) + conditional_regions += [animal_dragon_region] + + animal_unicorn_region_locations = [ + LocationName.animal_unicorn, + LocationName.chao_unicorn_arms, + LocationName.chao_unicorn_ears, + LocationName.chao_unicorn_forehead, + LocationName.chao_unicorn_legs, + LocationName.chao_unicorn_tail, + ] + animal_unicorn_region = create_region(multiworld, player, active_locations, LocationName.animal_unicorn, + animal_unicorn_region_locations) + conditional_regions += [animal_unicorn_region] + + animal_phoenix_region_locations = [ + LocationName.animal_phoenix, + LocationName.chao_phoenix_forehead, + LocationName.chao_phoenix_legs, + LocationName.chao_phoenix_tail, + LocationName.chao_phoenix_wings, + ] + animal_phoenix_region = create_region(multiworld, player, active_locations, LocationName.animal_phoenix, + animal_phoenix_region_locations) + conditional_regions += [animal_phoenix_region] + + if world.options.chao_kindergarten: + chao_kindergarten_region_locations = list(chao_kindergarten_location_table.keys()) + list(chao_kindergarten_basics_location_table.keys()) + chao_kindergarten_region = create_region(multiworld, player, active_locations, LocationName.chao_kindergarten_region, + chao_kindergarten_region_locations) + conditional_regions += [chao_kindergarten_region] + + if world.options.black_market_slots.value > 0: + + black_market_region_locations = list(black_market_location_table.keys()) + black_market_region = create_region(multiworld, player, active_locations, LocationName.black_market_region, + black_market_region_locations) + conditional_regions += [black_market_region] kart_race_beginner_region_locations = [] - if world.kart_race_checks[player] == 2: + if world.options.kart_race_checks == 2: kart_race_beginner_region_locations.extend([ LocationName.kart_race_beginner_sonic, LocationName.kart_race_beginner_tails, @@ -1404,13 +1680,13 @@ def create_regions(world, player: int, active_locations): LocationName.kart_race_beginner_eggman, LocationName.kart_race_beginner_rouge, ]) - if world.kart_race_checks[player] == 1: + if world.options.kart_race_checks == 1: kart_race_beginner_region_locations.append(LocationName.kart_race_beginner) - kart_race_beginner_region = create_region(world, player, active_locations, LocationName.kart_race_beginner_region, + kart_race_beginner_region = create_region(multiworld, player, active_locations, LocationName.kart_race_beginner_region, kart_race_beginner_region_locations) kart_race_standard_region_locations = [] - if world.kart_race_checks[player] == 2: + if world.options.kart_race_checks == 2: kart_race_standard_region_locations.extend([ LocationName.kart_race_standard_sonic, LocationName.kart_race_standard_tails, @@ -1419,13 +1695,13 @@ def create_regions(world, player: int, active_locations): LocationName.kart_race_standard_eggman, LocationName.kart_race_standard_rouge, ]) - if world.kart_race_checks[player] == 1: + if world.options.kart_race_checks == 1: kart_race_standard_region_locations.append(LocationName.kart_race_standard) - kart_race_standard_region = create_region(world, player, active_locations, LocationName.kart_race_standard_region, + kart_race_standard_region = create_region(multiworld, player, active_locations, LocationName.kart_race_standard_region, kart_race_standard_region_locations) kart_race_expert_region_locations = [] - if world.kart_race_checks[player] == 2: + if world.options.kart_race_checks == 2: kart_race_expert_region_locations.extend([ LocationName.kart_race_expert_sonic, LocationName.kart_race_expert_tails, @@ -1434,51 +1710,56 @@ def create_regions(world, player: int, active_locations): LocationName.kart_race_expert_eggman, LocationName.kart_race_expert_rouge, ]) - if world.kart_race_checks[player] == 1: + if world.options.kart_race_checks == 1: kart_race_expert_region_locations.append(LocationName.kart_race_expert) - kart_race_expert_region = create_region(world, player, active_locations, LocationName.kart_race_expert_region, + kart_race_expert_region = create_region(multiworld, player, active_locations, LocationName.kart_race_expert_region, kart_race_expert_region_locations) - if world.goal[player] == 3: + if world.options.goal == 3: grand_prix_region_locations = [ LocationName.grand_prix, ] - grand_prix_region = create_region(world, player, active_locations, LocationName.grand_prix_region, + grand_prix_region = create_region(multiworld, player, active_locations, LocationName.grand_prix_region, grand_prix_region_locations) - world.regions += [grand_prix_region] - - if world.goal[player] in [0, 2, 4, 5, 6]: + conditional_regions += [grand_prix_region] + elif world.options.goal in [0, 2, 4, 5, 6]: biolizard_region_locations = [ LocationName.finalhazard, ] - biolizard_region = create_region(world, player, active_locations, LocationName.biolizard_region, + biolizard_region = create_region(multiworld, player, active_locations, LocationName.biolizard_region, biolizard_region_locations) - world.regions += [biolizard_region] + conditional_regions += [biolizard_region] + elif world.options.goal == 7: + chaos_chao_region_locations = [ + LocationName.chaos_chao, + ] + chaos_chao_region = create_region(multiworld, player, active_locations, LocationName.chaos_chao_region, + chaos_chao_region_locations) + conditional_regions += [chaos_chao_region] - if world.goal[player] in [1, 2]: + if world.options.goal in [1, 2]: green_hill_region_locations = [ LocationName.green_hill, 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(multiworld, player, active_locations, LocationName.green_hill_region, green_hill_region_locations) - world.regions += [green_hill_region] + conditional_regions += [green_hill_region] - if world.goal[player] in [4, 5, 6]: + if world.options.goal 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 = create_region(multiworld, player, active_locations, "Boss Rush " + str(i + 1), boss_region_locations) - world.regions += [boss_region] + conditional_regions += [boss_region] # Set up the regions correctly. - world.regions += [ + multiworld.regions += [ menu_region, - gate_0_region, city_escape_region, metal_harbor_region, green_forest_region, @@ -1510,32 +1791,38 @@ def create_regions(world, player: int, active_locations): route_280_region, mad_space_region, cannon_core_region, - chao_garden_beginner_region, - chao_garden_intermediate_region, - chao_garden_expert_region, + chao_race_beginner_region, + chao_karate_beginner_region, + chao_race_intermediate_region, + chao_karate_intermediate_region, + chao_race_expert_region, + chao_karate_expert_region, + chao_karate_super_region, kart_race_beginner_region, kart_race_standard_region, kart_race_expert_region, ] + multiworld.regions += conditional_regions -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): + +def connect_regions(multiworld: MultiWorld, world: World, player: int, 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] = {} - connect(world, player, names, 'Menu', LocationName.gate_0_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.cannon_core_region, + connect(multiworld, player, names, 'Menu', LocationName.gate_0_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.cannon_core_region, lambda state: (state.has(ItemName.emblem, player, cannon_core_emblems))) - if world.goal[player] == 0: + if world.options.goal == 0: required_mission_name = first_cannons_core_mission - if world.required_cannons_core_missions[player].value == 1: + if world.options.required_cannons_core_missions.value == 1: required_mission_name = final_cannons_core_mission - connect(world, player, names, LocationName.cannon_core_region, LocationName.biolizard_region, + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.biolizard_region, lambda state: (state.can_reach(required_mission_name, "Location", player))) - elif world.goal[player] in [1, 2]: - connect(world, player, names, 'Menu', LocationName.green_hill_region, + elif world.options.goal in [1, 2]: + connect(multiworld, player, names, 'Menu', LocationName.green_hill_region, lambda state: (state.has(ItemName.white_emerald, player) and state.has(ItemName.red_emerald, player) and state.has(ItemName.cyan_emerald, player) and @@ -1543,23 +1830,23 @@ def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_em state.has(ItemName.green_emerald, player) and state.has(ItemName.yellow_emerald, player) and state.has(ItemName.blue_emerald, player))) - if world.goal[player] == 2: - connect(world, player, names, LocationName.green_hill_region, LocationName.biolizard_region) - elif world.goal[player] == 3: - 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: + if world.options.goal == 2: + connect(multiworld, player, names, LocationName.green_hill_region, LocationName.biolizard_region) + elif world.options.goal == 3: + connect(multiworld, player, names, LocationName.kart_race_expert_region, LocationName.grand_prix_region) + elif world.options.goal in [4, 5, 6]: + if world.options.goal == 4: + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.boss_rush_1_region) + elif world.options.goal == 5: required_mission_name = first_cannons_core_mission - if world.required_cannons_core_missions[player].value == 1: + if world.options.required_cannons_core_missions.value == 1: required_mission_name = final_cannons_core_mission - connect(world, player, names, LocationName.cannon_core_region, LocationName.boss_rush_1_region, + connect(multiworld, 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, + elif world.options.goal == 6: + connect(multiworld, 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 @@ -1570,134 +1857,576 @@ def connect_regions(world, player, gates: typing.List[LevelGate], cannon_core_em 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), + connect(multiworld, 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(multiworld, player, names, "Boss Rush " + str(i + 1), "Boss Rush " + str(i + 2)) - connect(world, player, names, LocationName.boss_rush_16_region, LocationName.biolizard_region) + connect(multiworld, player, names, LocationName.boss_rush_16_region, LocationName.biolizard_region) + elif world.options.goal == 7: + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chaos_chao, + lambda state: (state.has_all(chao_animal_event_location_table.keys(), player))) 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(multiworld, player, names, LocationName.gate_0_region, shuffleable_regions[gates[0].gate_levels[i]]) gates_len = len(gates) if gates_len >= 2: - connect(world, player, names, LocationName.gate_0_region, LocationName.gate_1_boss_region, + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.gate_1_boss_region, lambda state: (state.has(ItemName.emblem, player, gates[1].gate_emblem_count))) if gate_bosses[1] == all_gate_bosses_table[king_boom_boo]: - connect(world, player, names, LocationName.gate_1_boss_region, LocationName.gate_1_region, + connect(multiworld, player, names, LocationName.gate_1_boss_region, LocationName.gate_1_region, lambda state: (state.has(ItemName.knuckles_shovel_claws, player))) else: - connect(world, player, names, LocationName.gate_1_boss_region, LocationName.gate_1_region) + connect(multiworld, player, names, LocationName.gate_1_boss_region, LocationName.gate_1_region) for i in range(len(gates[1].gate_levels)): - connect(world, player, names, LocationName.gate_1_region, shuffleable_regions[gates[1].gate_levels[i]]) + connect(multiworld, player, names, LocationName.gate_1_region, shuffleable_regions[gates[1].gate_levels[i]]) if gates_len >= 3: - connect(world, player, names, LocationName.gate_1_region, LocationName.gate_2_boss_region, + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.gate_2_boss_region, lambda state: (state.has(ItemName.emblem, player, gates[2].gate_emblem_count))) if gate_bosses[2] == all_gate_bosses_table[king_boom_boo]: - connect(world, player, names, LocationName.gate_2_boss_region, LocationName.gate_2_region, + connect(multiworld, player, names, LocationName.gate_2_boss_region, LocationName.gate_2_region, lambda state: (state.has(ItemName.knuckles_shovel_claws, player))) else: - connect(world, player, names, LocationName.gate_2_boss_region, LocationName.gate_2_region) + connect(multiworld, player, names, LocationName.gate_2_boss_region, LocationName.gate_2_region) for i in range(len(gates[2].gate_levels)): - connect(world, player, names, LocationName.gate_2_region, shuffleable_regions[gates[2].gate_levels[i]]) + connect(multiworld, player, names, LocationName.gate_2_region, shuffleable_regions[gates[2].gate_levels[i]]) if gates_len >= 4: - connect(world, player, names, LocationName.gate_2_region, LocationName.gate_3_boss_region, + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.gate_3_boss_region, lambda state: (state.has(ItemName.emblem, player, gates[3].gate_emblem_count))) if gate_bosses[3] == all_gate_bosses_table[king_boom_boo]: - connect(world, player, names, LocationName.gate_3_boss_region, LocationName.gate_3_region, + connect(multiworld, player, names, LocationName.gate_3_boss_region, LocationName.gate_3_region, lambda state: (state.has(ItemName.knuckles_shovel_claws, player))) else: - connect(world, player, names, LocationName.gate_3_boss_region, LocationName.gate_3_region) + connect(multiworld, player, names, LocationName.gate_3_boss_region, LocationName.gate_3_region) for i in range(len(gates[3].gate_levels)): - connect(world, player, names, LocationName.gate_3_region, shuffleable_regions[gates[3].gate_levels[i]]) + connect(multiworld, player, names, LocationName.gate_3_region, shuffleable_regions[gates[3].gate_levels[i]]) if gates_len >= 5: - connect(world, player, names, LocationName.gate_3_region, LocationName.gate_4_boss_region, + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.gate_4_boss_region, lambda state: (state.has(ItemName.emblem, player, gates[4].gate_emblem_count))) if gate_bosses[4] == all_gate_bosses_table[king_boom_boo]: - connect(world, player, names, LocationName.gate_4_boss_region, LocationName.gate_4_region, + connect(multiworld, player, names, LocationName.gate_4_boss_region, LocationName.gate_4_region, lambda state: (state.has(ItemName.knuckles_shovel_claws, player))) else: - connect(world, player, names, LocationName.gate_4_boss_region, LocationName.gate_4_region) + connect(multiworld, player, names, LocationName.gate_4_boss_region, LocationName.gate_4_region) for i in range(len(gates[4].gate_levels)): - connect(world, player, names, LocationName.gate_4_region, shuffleable_regions[gates[4].gate_levels[i]]) + connect(multiworld, player, names, LocationName.gate_4_region, shuffleable_regions[gates[4].gate_levels[i]]) if gates_len >= 6: - connect(world, player, names, LocationName.gate_4_region, LocationName.gate_5_boss_region, + connect(multiworld, player, names, LocationName.gate_4_region, LocationName.gate_5_boss_region, lambda state: (state.has(ItemName.emblem, player, gates[5].gate_emblem_count))) if gate_bosses[5] == all_gate_bosses_table[king_boom_boo]: - connect(world, player, names, LocationName.gate_5_boss_region, LocationName.gate_5_region, + connect(multiworld, player, names, LocationName.gate_5_boss_region, LocationName.gate_5_region, lambda state: (state.has(ItemName.knuckles_shovel_claws, player))) else: - connect(world, player, names, LocationName.gate_5_boss_region, LocationName.gate_5_region) + connect(multiworld, player, names, LocationName.gate_5_boss_region, LocationName.gate_5_region) for i in range(len(gates[5].gate_levels)): - connect(world, player, names, LocationName.gate_5_region, shuffleable_regions[gates[5].gate_levels[i]]) + connect(multiworld, player, names, LocationName.gate_5_region, shuffleable_regions[gates[5].gate_levels[i]]) if gates_len == 1: - connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_beginner_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_intermediate_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_expert_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_race_intermediate_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_race_expert_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_standard_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_expert_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_karate_beginner_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_karate_intermediate_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_karate_expert_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_karate_super_region) + + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.kart_race_standard_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.kart_race_expert_region) + + if world.options.chao_kindergarten: + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_kindergarten_region) elif gates_len == 2: - connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_beginner_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_intermediate_region) - connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_expert_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_race_intermediate_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_race_expert_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_standard_region) - connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_expert_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_karate_beginner_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_karate_intermediate_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_karate_expert_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_karate_super_region) + + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.kart_race_standard_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.kart_race_expert_region) + + if world.options.chao_kindergarten: + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_kindergarten_region) elif gates_len == 3: - connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_beginner_region) - connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_intermediate_region) - connect(world, player, names, LocationName.gate_2_region, LocationName.chao_garden_expert_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_race_intermediate_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.chao_race_expert_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region) - connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_standard_region) - connect(world, player, names, LocationName.gate_2_region, LocationName.kart_race_expert_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_karate_beginner_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_karate_intermediate_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.chao_karate_expert_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.chao_karate_super_region) + + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.kart_race_standard_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.kart_race_expert_region) + + if world.options.chao_kindergarten: + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_kindergarten_region) elif gates_len == 4: - connect(world, player, names, LocationName.gate_0_region, LocationName.chao_garden_beginner_region) - connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_intermediate_region) - connect(world, player, names, LocationName.gate_3_region, LocationName.chao_garden_expert_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_race_intermediate_region) + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.chao_race_expert_region) - connect(world, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region) - connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_standard_region) - connect(world, player, names, LocationName.gate_3_region, LocationName.kart_race_expert_region) + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.chao_karate_beginner_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_karate_intermediate_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.chao_karate_expert_region) + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.chao_karate_super_region) + + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.kart_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.kart_race_standard_region) + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.kart_race_expert_region) + + if world.options.chao_kindergarten: + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.chao_kindergarten_region) elif gates_len == 5: - connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_beginner_region) - connect(world, player, names, LocationName.gate_2_region, LocationName.chao_garden_intermediate_region) - connect(world, player, names, LocationName.gate_3_region, LocationName.chao_garden_expert_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.chao_race_intermediate_region) + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.chao_race_expert_region) - connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_beginner_region) - connect(world, player, names, LocationName.gate_2_region, LocationName.kart_race_standard_region) - connect(world, player, names, LocationName.gate_3_region, LocationName.kart_race_expert_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_karate_beginner_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.chao_karate_intermediate_region) + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.chao_karate_expert_region) + connect(multiworld, player, names, LocationName.gate_4_region, LocationName.chao_karate_super_region) + + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.kart_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.kart_race_standard_region) + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.kart_race_expert_region) + + if world.options.chao_kindergarten: + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.chao_kindergarten_region) elif gates_len >= 6: - connect(world, player, names, LocationName.gate_1_region, LocationName.chao_garden_beginner_region) - connect(world, player, names, LocationName.gate_2_region, LocationName.chao_garden_intermediate_region) - connect(world, player, names, LocationName.gate_4_region, LocationName.chao_garden_expert_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.chao_race_intermediate_region) + connect(multiworld, player, names, LocationName.gate_4_region, LocationName.chao_race_expert_region) - connect(world, player, names, LocationName.gate_1_region, LocationName.kart_race_beginner_region) - connect(world, player, names, LocationName.gate_2_region, LocationName.kart_race_standard_region) - connect(world, player, names, LocationName.gate_4_region, LocationName.kart_race_expert_region) + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.chao_karate_beginner_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.chao_karate_intermediate_region) + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.chao_karate_expert_region) + connect(multiworld, player, names, LocationName.gate_4_region, LocationName.chao_karate_super_region) + + connect(multiworld, player, names, LocationName.gate_1_region, LocationName.kart_race_beginner_region) + connect(multiworld, player, names, LocationName.gate_2_region, LocationName.kart_race_standard_region) + connect(multiworld, player, names, LocationName.gate_4_region, LocationName.kart_race_expert_region) + + if world.options.chao_kindergarten: + connect(multiworld, player, names, LocationName.gate_3_region, LocationName.chao_kindergarten_region) + + stat_checks_per_gate = world.options.chao_stats.value / (gates_len) + for index in range(1, world.options.chao_stats.value + 1): + if (index % world.options.chao_stats_frequency.value) == (world.options.chao_stats.value % world.options.chao_stats_frequency.value): + gate_val = math.ceil(index / stat_checks_per_gate) - 1 + gate_region = multiworld.get_region("Gate " + str(gate_val), player) + + loc_name_swim = LocationName.chao_stat_swim_base + str(index) + loc_id_swim = chao_stat_swim_table[loc_name_swim] + location_swim = SA2BLocation(player, loc_name_swim, loc_id_swim, gate_region) + gate_region.locations.append(location_swim) + + loc_name_fly = LocationName.chao_stat_fly_base + str(index) + loc_id_fly = chao_stat_fly_table[loc_name_fly] + location_fly = SA2BLocation(player, loc_name_fly, loc_id_fly, gate_region) + gate_region.locations.append(location_fly) + + loc_name_run = LocationName.chao_stat_run_base + str(index) + loc_id_run = chao_stat_run_table[loc_name_run] + location_run = SA2BLocation(player, loc_name_run, loc_id_run, gate_region) + gate_region.locations.append(location_run) + + loc_name_power = LocationName.chao_stat_power_base + str(index) + loc_id_power = chao_stat_power_table[loc_name_power] + location_power = SA2BLocation(player, loc_name_power, loc_id_power, gate_region) + gate_region.locations.append(location_power) + + if world.options.chao_stats_stamina: + loc_name_stamina = LocationName.chao_stat_stamina_base + str(index) + loc_id_stamina = chao_stat_stamina_table[loc_name_stamina] + location_stamina = SA2BLocation(player, loc_name_stamina, loc_id_stamina, gate_region) + gate_region.locations.append(location_stamina) + + if world.options.chao_stats_hidden: + loc_name_luck = LocationName.chao_stat_luck_base + str(index) + loc_id_luck = chao_stat_luck_table[loc_name_luck] + location_luck = SA2BLocation(player, loc_name_luck, loc_id_luck, gate_region) + gate_region.locations.append(location_luck) + + loc_name_intelligence = LocationName.chao_stat_intelligence_base + str(index) + loc_id_intelligence = chao_stat_intelligence_table[loc_name_intelligence] + location_intelligence = SA2BLocation(player, loc_name_intelligence, loc_id_intelligence, gate_region) + gate_region.locations.append(location_intelligence) + + # Handle access to Animal Parts + if world.options.goal == 7 or world.options.chao_animal_parts: + connect(multiworld, player, names, LocationName.city_escape_region, LocationName.animal_rabbit) + connect(multiworld, player, names, LocationName.city_escape_region, LocationName.animal_skunk) + connect(multiworld, player, names, LocationName.city_escape_region, LocationName.animal_sheep) + connect(multiworld, player, names, LocationName.city_escape_region, LocationName.animal_raccoon) + + connect(multiworld, player, names, LocationName.wild_canyon_region, LocationName.animal_cheetah) + connect(multiworld, player, names, LocationName.wild_canyon_region, LocationName.animal_peacock) + connect(multiworld, player, names, LocationName.wild_canyon_region, LocationName.animal_condor) + connect(multiworld, player, names, LocationName.wild_canyon_region, LocationName.animal_sheep) + + connect(multiworld, player, names, LocationName.prison_lane_region, LocationName.animal_otter) + connect(multiworld, player, names, LocationName.prison_lane_region, LocationName.animal_tiger) + connect(multiworld, player, names, LocationName.prison_lane_region, LocationName.animal_gorilla) + connect(multiworld, player, names, LocationName.prison_lane_region, LocationName.animal_sheep) + connect(multiworld, player, names, LocationName.prison_lane_region, LocationName.animal_unicorn, + lambda state: (state.has(ItemName.tails_booster, player))) + + connect(multiworld, player, names, LocationName.metal_harbor_region, LocationName.animal_penguin) + connect(multiworld, player, names, LocationName.metal_harbor_region, LocationName.animal_seal) + connect(multiworld, player, names, LocationName.metal_harbor_region, LocationName.animal_peacock) + connect(multiworld, player, names, LocationName.metal_harbor_region, LocationName.animal_raccoon) + + connect(multiworld, player, names, LocationName.green_forest_region, LocationName.animal_rabbit) + connect(multiworld, player, names, LocationName.green_forest_region, LocationName.animal_cheetah) + connect(multiworld, player, names, LocationName.green_forest_region, LocationName.animal_parrot) + connect(multiworld, player, names, LocationName.green_forest_region, LocationName.animal_raccoon) + connect(multiworld, player, names, LocationName.green_forest_region, LocationName.animal_halffish) + + connect(multiworld, player, names, LocationName.pumpkin_hill_region, LocationName.animal_cheetah) + connect(multiworld, player, names, LocationName.pumpkin_hill_region, LocationName.animal_warthog) + connect(multiworld, player, names, LocationName.pumpkin_hill_region, LocationName.animal_skeleton_dog) + connect(multiworld, player, names, LocationName.pumpkin_hill_region, LocationName.animal_bat) + + connect(multiworld, player, names, LocationName.mission_street_region, LocationName.animal_rabbit) + connect(multiworld, player, names, LocationName.mission_street_region, LocationName.animal_warthog) + connect(multiworld, player, names, LocationName.mission_street_region, LocationName.animal_gorilla) + connect(multiworld, player, names, LocationName.mission_street_region, LocationName.animal_sheep) + + connect(multiworld, player, names, LocationName.aquatic_mine_region, LocationName.animal_penguin) + connect(multiworld, player, names, LocationName.aquatic_mine_region, LocationName.animal_seal) + connect(multiworld, player, names, LocationName.aquatic_mine_region, LocationName.animal_condor) + connect(multiworld, player, names, LocationName.aquatic_mine_region, LocationName.animal_skunk) + connect(multiworld, player, names, LocationName.aquatic_mine_region, LocationName.animal_dragon) + + connect(multiworld, player, names, LocationName.hidden_base_region, LocationName.animal_penguin, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.hidden_base_region, LocationName.animal_otter, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.hidden_base_region, LocationName.animal_tiger, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.hidden_base_region, LocationName.animal_skunk) + connect(multiworld, player, names, LocationName.hidden_base_region, LocationName.animal_halffish, + lambda state: (state.has(ItemName.tails_booster, player))) + + connect(multiworld, player, names, LocationName.pyramid_cave_region, LocationName.animal_peacock) + connect(multiworld, player, names, LocationName.pyramid_cave_region, LocationName.animal_condor) + connect(multiworld, player, names, LocationName.pyramid_cave_region, LocationName.animal_sheep) + connect(multiworld, player, names, LocationName.pyramid_cave_region, LocationName.animal_bat) + + connect(multiworld, player, names, LocationName.death_chamber_region, LocationName.animal_rabbit) + connect(multiworld, player, names, LocationName.death_chamber_region, LocationName.animal_tiger) + connect(multiworld, player, names, LocationName.death_chamber_region, LocationName.animal_gorilla) + connect(multiworld, player, names, LocationName.death_chamber_region, LocationName.animal_skunk) + + connect(multiworld, player, names, LocationName.eternal_engine_region, LocationName.animal_warthog) + connect(multiworld, player, names, LocationName.eternal_engine_region, LocationName.animal_parrot, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.eternal_engine_region, LocationName.animal_condor) + connect(multiworld, player, names, LocationName.eternal_engine_region, LocationName.animal_raccoon) + + connect(multiworld, player, names, LocationName.meteor_herd_region, LocationName.animal_penguin) + connect(multiworld, player, names, LocationName.meteor_herd_region, LocationName.animal_seal) + connect(multiworld, player, names, LocationName.meteor_herd_region, LocationName.animal_rabbit) + connect(multiworld, player, names, LocationName.meteor_herd_region, LocationName.animal_sheep) + connect(multiworld, player, names, LocationName.meteor_herd_region, LocationName.animal_phoenix) + + connect(multiworld, player, names, LocationName.crazy_gadget_region, LocationName.animal_seal) + connect(multiworld, player, names, LocationName.crazy_gadget_region, LocationName.animal_bear) + connect(multiworld, player, names, LocationName.crazy_gadget_region, LocationName.animal_tiger) + + connect(multiworld, player, names, LocationName.final_rush_region, LocationName.animal_penguin) + connect(multiworld, player, names, LocationName.final_rush_region, LocationName.animal_peacock) + connect(multiworld, player, names, LocationName.final_rush_region, LocationName.animal_condor) + connect(multiworld, player, names, LocationName.final_rush_region, LocationName.animal_sheep) + connect(multiworld, player, names, LocationName.final_rush_region, LocationName.animal_dragon, + lambda state: (state.has(ItemName.sonic_bounce_bracelet, player))) + + connect(multiworld, player, names, LocationName.iron_gate_region, LocationName.animal_rabbit) + connect(multiworld, player, names, LocationName.iron_gate_region, LocationName.animal_tiger) + connect(multiworld, player, names, LocationName.iron_gate_region, LocationName.animal_gorilla) + connect(multiworld, player, names, LocationName.iron_gate_region, LocationName.animal_skunk) + + connect(multiworld, player, names, LocationName.dry_lagoon_region, LocationName.animal_penguin) + connect(multiworld, player, names, LocationName.dry_lagoon_region, LocationName.animal_otter) + connect(multiworld, player, names, LocationName.dry_lagoon_region, LocationName.animal_peacock) + connect(multiworld, player, names, LocationName.dry_lagoon_region, LocationName.animal_sheep) + connect(multiworld, player, names, LocationName.dry_lagoon_region, LocationName.animal_unicorn) + + connect(multiworld, player, names, LocationName.sand_ocean_region, LocationName.animal_peacock) + connect(multiworld, player, names, LocationName.sand_ocean_region, LocationName.animal_parrot) + connect(multiworld, player, names, LocationName.sand_ocean_region, LocationName.animal_raccoon) + connect(multiworld, player, names, LocationName.sand_ocean_region, LocationName.animal_bat) + + connect(multiworld, player, names, LocationName.radical_highway_region, LocationName.animal_seal) + connect(multiworld, player, names, LocationName.radical_highway_region, LocationName.animal_cheetah) + connect(multiworld, player, names, LocationName.radical_highway_region, LocationName.animal_warthog) + connect(multiworld, player, names, LocationName.radical_highway_region, LocationName.animal_raccoon) + + connect(multiworld, player, names, LocationName.egg_quarters_region, LocationName.animal_bear) + connect(multiworld, player, names, LocationName.egg_quarters_region, LocationName.animal_gorilla) + connect(multiworld, player, names, LocationName.egg_quarters_region, LocationName.animal_parrot) + connect(multiworld, player, names, LocationName.egg_quarters_region, LocationName.animal_skunk) + connect(multiworld, player, names, LocationName.egg_quarters_region, LocationName.animal_halffish) + + connect(multiworld, player, names, LocationName.lost_colony_region, LocationName.animal_rabbit) + connect(multiworld, player, names, LocationName.lost_colony_region, LocationName.animal_warthog) + connect(multiworld, player, names, LocationName.lost_colony_region, LocationName.animal_bat) + + connect(multiworld, player, names, LocationName.weapons_bed_region, LocationName.animal_seal) + connect(multiworld, player, names, LocationName.weapons_bed_region, LocationName.animal_otter) + connect(multiworld, player, names, LocationName.weapons_bed_region, LocationName.animal_cheetah) + connect(multiworld, player, names, LocationName.weapons_bed_region, LocationName.animal_sheep) + + connect(multiworld, player, names, LocationName.security_hall_region, LocationName.animal_tiger) + connect(multiworld, player, names, LocationName.security_hall_region, LocationName.animal_parrot) + connect(multiworld, player, names, LocationName.security_hall_region, LocationName.animal_condor) + connect(multiworld, player, names, LocationName.security_hall_region, LocationName.animal_raccoon) + + connect(multiworld, player, names, LocationName.white_jungle_region, LocationName.animal_bear) + connect(multiworld, player, names, LocationName.white_jungle_region, LocationName.animal_peacock) + connect(multiworld, player, names, LocationName.white_jungle_region, LocationName.animal_parrot) + connect(multiworld, player, names, LocationName.white_jungle_region, LocationName.animal_skunk) + + connect(multiworld, player, names, LocationName.sky_rail_region, LocationName.animal_bear) + connect(multiworld, player, names, LocationName.sky_rail_region, LocationName.animal_tiger) + connect(multiworld, player, names, LocationName.sky_rail_region, LocationName.animal_condor) + connect(multiworld, player, names, LocationName.sky_rail_region, LocationName.animal_sheep) + + connect(multiworld, player, names, LocationName.mad_space_region, LocationName.animal_peacock) + connect(multiworld, player, names, LocationName.mad_space_region, LocationName.animal_parrot) + + connect(multiworld, player, names, LocationName.cosmic_wall_region, LocationName.animal_otter, + lambda state: (state.has(ItemName.eggman_jet_engine, player))) + connect(multiworld, player, names, LocationName.cosmic_wall_region, LocationName.animal_rabbit) + connect(multiworld, player, names, LocationName.cosmic_wall_region, LocationName.animal_cheetah, + lambda state: (state.has(ItemName.eggman_jet_engine, player))) + connect(multiworld, player, names, LocationName.cosmic_wall_region, LocationName.animal_sheep, + lambda state: (state.has(ItemName.eggman_jet_engine, player))) + connect(multiworld, player, names, LocationName.cosmic_wall_region, LocationName.animal_dragon, + lambda state: (state.has(ItemName.eggman_jet_engine, player))) + + connect(multiworld, player, names, LocationName.final_chase_region, LocationName.animal_penguin) + connect(multiworld, player, names, LocationName.final_chase_region, LocationName.animal_otter) + connect(multiworld, player, names, LocationName.final_chase_region, LocationName.animal_tiger) + connect(multiworld, player, names, LocationName.final_chase_region, LocationName.animal_skunk) + connect(multiworld, player, names, LocationName.final_chase_region, LocationName.animal_phoenix) + + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_seal) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_bear, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_gorilla) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_skunk) + + if world.options.goal in [1, 2]: + connect(multiworld, player, names, LocationName.green_hill_region, LocationName.animal_penguin) + connect(multiworld, player, names, LocationName.green_hill_region, LocationName.animal_otter) + connect(multiworld, player, names, LocationName.green_hill_region, LocationName.animal_gorilla) + connect(multiworld, player, names, LocationName.green_hill_region, LocationName.animal_raccoon) + connect(multiworld, player, names, LocationName.green_hill_region, LocationName.animal_unicorn) + + if world.options.logic_difficulty.value == 0: + connect(multiworld, player, names, LocationName.metal_harbor_region, LocationName.animal_phoenix, + lambda state: (state.has(ItemName.sonic_light_shoes, player))) + + connect(multiworld, player, names, LocationName.crazy_gadget_region, LocationName.animal_skunk, + lambda state: (state.has(ItemName.sonic_bounce_bracelet, player))) + connect(multiworld, player, names, LocationName.crazy_gadget_region, LocationName.animal_phoenix, + 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))) + + connect(multiworld, player, names, LocationName.weapons_bed_region, LocationName.animal_phoenix, + lambda state: (state.has(ItemName.eggman_jet_engine, player) and + state.has(ItemName.eggman_large_cannon, player))) + + connect(multiworld, player, names, LocationName.mad_space_region, LocationName.animal_gorilla, + lambda state: (state.has(ItemName.rouge_iron_boots, player))) + connect(multiworld, player, names, LocationName.mad_space_region, LocationName.animal_raccoon, + lambda state: (state.has(ItemName.rouge_iron_boots, player))) + connect(multiworld, player, names, LocationName.mad_space_region, LocationName.animal_halffish, + lambda state: (state.has(ItemName.rouge_iron_boots, player))) + + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_otter, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.eggman_jet_engine, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_rabbit, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.eggman_jet_engine, player) and + state.has(ItemName.knuckles_air_necklace, player) and + state.has(ItemName.knuckles_hammer_gloves, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_cheetah, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.eggman_jet_engine, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_warthog, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.eggman_jet_engine, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_parrot, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.eggman_jet_engine, 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)))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_condor, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.eggman_jet_engine, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_raccoon, + lambda state: (state.has(ItemName.tails_booster, player) and + (state.has(ItemName.eggman_jet_engine, player) or + state.has(ItemName.eggman_large_cannon, player)))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_phoenix, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.eggman_jet_engine, player))) + + elif world.options.logic_difficulty.value == 1: + connect(multiworld, player, names, LocationName.metal_harbor_region, LocationName.animal_phoenix) + + connect(multiworld, player, names, LocationName.crazy_gadget_region, LocationName.animal_skunk) + connect(multiworld, player, names, LocationName.crazy_gadget_region, LocationName.animal_phoenix, + lambda state: (state.has(ItemName.sonic_light_shoes, player) and + state.has(ItemName.sonic_flame_ring, player))) + + connect(multiworld, player, names, LocationName.weapons_bed_region, LocationName.animal_phoenix, + lambda state: (state.has(ItemName.eggman_jet_engine, player))) + + connect(multiworld, player, names, LocationName.mad_space_region, LocationName.animal_gorilla) + connect(multiworld, player, names, LocationName.mad_space_region, LocationName.animal_raccoon) + connect(multiworld, player, names, LocationName.mad_space_region, LocationName.animal_halffish) + + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_otter, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_rabbit, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.knuckles_hammer_gloves, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_cheetah, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_warthog, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_parrot, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.knuckles_hammer_gloves, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_condor, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_raccoon, + lambda state: (state.has(ItemName.tails_booster, player))) + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_phoenix, + lambda state: (state.has(ItemName.tails_booster, player))) + + if world.options.keysanity: + connect(multiworld, player, names, LocationName.wild_canyon_region, LocationName.animal_dragon, + lambda state: (state.has(ItemName.knuckles_shovel_claws, player))) + + connect(multiworld, player, names, LocationName.mission_street_region, LocationName.animal_phoenix, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.tails_bazooka, player))) + + connect(multiworld, player, names, LocationName.pyramid_cave_region, LocationName.animal_skeleton_dog, + lambda state: (state.has(ItemName.sonic_light_shoes, player) and + state.has(ItemName.sonic_flame_ring, player))) + + connect(multiworld, player, names, LocationName.lost_colony_region, LocationName.animal_raccoon, + lambda state: (state.has(ItemName.eggman_jet_engine, player))) + + if world.options.logic_difficulty.value == 0: + connect(multiworld, player, names, LocationName.iron_gate_region, LocationName.animal_dragon, + lambda state: (state.has(ItemName.eggman_jet_engine, player) and + state.has(ItemName.eggman_large_cannon, player))) + + connect(multiworld, player, names, LocationName.sand_ocean_region, LocationName.animal_skeleton_dog, + lambda state: (state.has(ItemName.eggman_jet_engine, player) and + state.has(ItemName.eggman_large_cannon, player))) + if world.options.logic_difficulty.value == 1: + connect(multiworld, player, names, LocationName.iron_gate_region, LocationName.animal_dragon, + lambda state: (state.has(ItemName.eggman_jet_engine, player))) + + connect(multiworld, player, names, LocationName.sand_ocean_region, LocationName.animal_skeleton_dog, + lambda state: (state.has(ItemName.eggman_jet_engine, player))) + + else: + connect(multiworld, player, names, LocationName.city_escape_region, LocationName.animal_unicorn) + + connect(multiworld, player, names, LocationName.wild_canyon_region, LocationName.animal_dragon) + + connect(multiworld, player, names, LocationName.pumpkin_hill_region, LocationName.animal_halffish) + + connect(multiworld, player, names, LocationName.mission_street_region, LocationName.animal_phoenix, + lambda state: (state.has(ItemName.tails_booster, player))) + + connect(multiworld, player, names, LocationName.death_chamber_region, LocationName.animal_skeleton_dog, + lambda state: (state.has(ItemName.knuckles_shovel_claws, player) and + state.has(ItemName.knuckles_hammer_gloves, player))) + + connect(multiworld, player, names, LocationName.eternal_engine_region, LocationName.animal_halffish, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.tails_bazooka, player))) + + connect(multiworld, player, names, LocationName.iron_gate_region, LocationName.animal_dragon) + + connect(multiworld, player, names, LocationName.sand_ocean_region, LocationName.animal_skeleton_dog) + + connect(multiworld, player, names, LocationName.radical_highway_region, LocationName.animal_unicorn) + + connect(multiworld, player, names, LocationName.lost_colony_region, LocationName.animal_raccoon) + connect(multiworld, player, names, LocationName.lost_colony_region, LocationName.animal_skeleton_dog) + + connect(multiworld, player, names, LocationName.security_hall_region, LocationName.animal_phoenix, + lambda state: (state.has(ItemName.rouge_pick_nails, player))) + + connect(multiworld, player, names, LocationName.sky_rail_region, LocationName.animal_phoenix) + + if world.options.logic_difficulty.value == 0: + connect(multiworld, player, names, LocationName.pyramid_cave_region, LocationName.animal_skeleton_dog, + 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))) + + connect(multiworld, player, names, LocationName.white_jungle_region, LocationName.animal_dragon, + lambda state: (state.has(ItemName.shadow_air_shoes, player))) + + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_dragon, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.eggman_jet_engine, player) and + state.has(ItemName.knuckles_air_necklace, player) and + state.has(ItemName.knuckles_hammer_gloves, player))) + elif world.options.logic_difficulty.value == 1: + connect(multiworld, player, names, LocationName.pyramid_cave_region, LocationName.animal_skeleton_dog) + + connect(multiworld, player, names, LocationName.white_jungle_region, LocationName.animal_dragon) + + connect(multiworld, player, names, LocationName.cannon_core_region, LocationName.animal_dragon, + lambda state: (state.has(ItemName.tails_booster, player) and + state.has(ItemName.knuckles_hammer_gloves, player))) + + if world.options.black_market_slots.value > 0: + connect(multiworld, player, names, LocationName.gate_0_region, LocationName.black_market_region) -def create_region(world: MultiWorld, player: int, active_locations, name: str, locations=None): - ret = Region(name, player, world) +def create_region(multiworld: MultiWorld, player: int, active_locations, name: str, locations=None): + ret = Region(name, player, multiworld) if locations: for location in locations: loc_id = active_locations.get(location, 0) @@ -1708,10 +2437,10 @@ def create_region(world: MultiWorld, player: int, active_locations, name: str, l return ret -def connect(world: MultiWorld, player: int, used_names: typing.Dict[str, int], source: str, target: str, +def connect(multiworld: MultiWorld, player: int, used_names: typing.Dict[str, int], source: str, target: str, rule: typing.Optional[typing.Callable] = None): - source_region = world.get_region(source, player) - target_region = world.get_region(target, player) + source_region = multiworld.get_region(source, player) + target_region = multiworld.get_region(target, player) if target not in used_names: used_names[target] = 1 diff --git a/worlds/sa2b/Rules.py b/worlds/sa2b/Rules.py index 146938db..6b7ad69c 100644 --- a/worlds/sa2b/Rules.py +++ b/worlds/sa2b/Rules.py @@ -1,6 +1,7 @@ import typing from BaseClasses import MultiWorld +from worlds.AutoWorld import World from .Names import LocationName, ItemName from .Locations import boss_gate_set from worlds.AutoWorld import LogicMixin @@ -19,7 +20,7 @@ def add_rule_safe(multiworld: MultiWorld, spot_name: str, player: int, rule: Col add_rule(location, rule) -def set_mission_progress_rules(world: MultiWorld, player: int, mission_map: typing.Dict[int, int], mission_count_map: typing.Dict[int, int]): +def set_mission_progress_rules(multiworld: MultiWorld, player: int, mission_map: typing.Dict[int, int], mission_count_map: typing.Dict[int, int]): for i in range(31): mission_count = mission_count_map[i] mission_order: typing.List[int] = mission_orders[mission_map[i]] @@ -33,58 +34,58 @@ def set_mission_progress_rules(world: MultiWorld, player: int, mission_map: typi prev_mission_number = mission_order[j - 1] location_name: str = stage_prefix + str(mission_number) prev_location_name: str = stage_prefix + str(prev_mission_number) - set_rule(world.get_location(location_name, player), + set_rule(multiworld.get_location(location_name, player), lambda state, prev_location_name=prev_location_name: state.can_reach(prev_location_name, "Location", player)) -def set_mission_upgrade_rules_standard(world: MultiWorld, player: int): +def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, player: int): # Mission 1 Upgrade Requirements - add_rule_safe(world, LocationName.metal_harbor_1, player, + add_rule_safe(multiworld, LocationName.metal_harbor_1, player, lambda state: state.has(ItemName.sonic_light_shoes, player)) - add_rule_safe(world, LocationName.pumpkin_hill_1, player, + add_rule_safe(multiworld, LocationName.pumpkin_hill_1, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule_safe(world, LocationName.mission_street_1, player, + add_rule_safe(multiworld, LocationName.mission_street_1, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.aquatic_mine_1, player, + add_rule_safe(multiworld, LocationName.aquatic_mine_1, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule_safe(world, LocationName.hidden_base_1, player, + add_rule_safe(multiworld, LocationName.hidden_base_1, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.pyramid_cave_1, player, + add_rule_safe(multiworld, LocationName.pyramid_cave_1, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.death_chamber_1, player, + add_rule_safe(multiworld, LocationName.death_chamber_1, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.eternal_engine_1, player, + add_rule_safe(multiworld, LocationName.eternal_engine_1, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule_safe(world, LocationName.meteor_herd_1, player, + add_rule_safe(multiworld, LocationName.meteor_herd_1, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.crazy_gadget_1, player, + add_rule_safe(multiworld, LocationName.crazy_gadget_1, 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_safe(world, LocationName.final_rush_1, player, + add_rule_safe(multiworld, LocationName.final_rush_1, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.egg_quarters_1, player, + add_rule_safe(multiworld, LocationName.egg_quarters_1, player, lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule_safe(world, LocationName.lost_colony_1, player, + add_rule_safe(multiworld, LocationName.lost_colony_1, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.weapons_bed_1, player, + add_rule_safe(multiworld, LocationName.weapons_bed_1, player, lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.security_hall_1, player, + add_rule_safe(multiworld, LocationName.security_hall_1, player, lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule_safe(world, LocationName.white_jungle_1, player, + add_rule_safe(multiworld, LocationName.white_jungle_1, player, lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule_safe(world, LocationName.mad_space_1, player, + add_rule_safe(multiworld, LocationName.mad_space_1, player, lambda state: state.has(ItemName.rouge_pick_nails, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.cosmic_wall_1, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_1, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cannon_core_1, player, + add_rule_safe(multiworld, LocationName.cannon_core_1, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.knuckles_hammer_gloves, player) and @@ -92,129 +93,128 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int): state.has(ItemName.sonic_bounce_bracelet, player)) # Mission 2 Upgrade Requirements - add_rule_safe(world, LocationName.metal_harbor_2, player, + add_rule_safe(multiworld, LocationName.metal_harbor_2, player, lambda state: state.has(ItemName.sonic_light_shoes, player)) - add_rule_safe(world, LocationName.mission_street_2, player, + add_rule_safe(multiworld, LocationName.mission_street_2, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.hidden_base_2, player, + add_rule_safe(multiworld, LocationName.hidden_base_2, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.death_chamber_2, player, + add_rule_safe(multiworld, LocationName.death_chamber_2, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.eternal_engine_2, player, - lambda state: state.has(ItemName.tails_booster, player) and - state.has(ItemName.tails_bazooka, player)) - add_rule_safe(world, LocationName.crazy_gadget_2, player, + add_rule_safe(multiworld, LocationName.eternal_engine_2, player, + lambda state: state.has(ItemName.tails_booster, player)) + add_rule_safe(multiworld, LocationName.crazy_gadget_2, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.lost_colony_2, player, + add_rule_safe(multiworld, LocationName.lost_colony_2, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.weapons_bed_2, player, + add_rule_safe(multiworld, LocationName.weapons_bed_2, player, lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.security_hall_2, player, + add_rule_safe(multiworld, LocationName.security_hall_2, player, lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule_safe(world, LocationName.mad_space_2, player, + add_rule_safe(multiworld, LocationName.mad_space_2, player, lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.cosmic_wall_2, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_2, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cannon_core_2, player, + add_rule_safe(multiworld, LocationName.cannon_core_2, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player)) # Mission 3 Upgrade Requirements - add_rule_safe(world, LocationName.city_escape_3, player, + add_rule_safe(multiworld, LocationName.city_escape_3, player, lambda state: state.has(ItemName.sonic_mystic_melody, player)) - add_rule_safe(world, LocationName.wild_canyon_3, player, + add_rule_safe(multiworld, LocationName.wild_canyon_3, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.knuckles_mystic_melody, player)) - add_rule_safe(world, LocationName.prison_lane_3, player, + add_rule_safe(multiworld, LocationName.prison_lane_3, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_mystic_melody, player)) - add_rule_safe(world, LocationName.metal_harbor_3, player, + add_rule_safe(multiworld, LocationName.metal_harbor_3, 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_safe(world, LocationName.green_forest_3, player, + add_rule_safe(multiworld, LocationName.green_forest_3, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and state.has(ItemName.sonic_mystic_melody, player)) - add_rule_safe(world, LocationName.pumpkin_hill_3, player, + add_rule_safe(multiworld, LocationName.pumpkin_hill_3, player, lambda state: state.has(ItemName.knuckles_mystic_melody, player)) - add_rule_safe(world, LocationName.mission_street_3, player, + add_rule_safe(multiworld, LocationName.mission_street_3, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_mystic_melody, player)) - add_rule_safe(world, LocationName.aquatic_mine_3, player, + add_rule_safe(multiworld, LocationName.aquatic_mine_3, player, lambda state: state.has(ItemName.knuckles_mystic_melody, player)) - add_rule_safe(world, LocationName.hidden_base_3, player, + add_rule_safe(multiworld, LocationName.hidden_base_3, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_mystic_melody, player)) - add_rule_safe(world, LocationName.pyramid_cave_3, player, + add_rule_safe(multiworld, LocationName.pyramid_cave_3, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and state.has(ItemName.sonic_mystic_melody, player)) - add_rule_safe(world, LocationName.death_chamber_3, player, + add_rule_safe(multiworld, LocationName.death_chamber_3, player, lambda state: state.has(ItemName.knuckles_mystic_melody, player) and state.has(ItemName.knuckles_air_necklace, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.eternal_engine_3, player, + add_rule_safe(multiworld, LocationName.eternal_engine_3, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_mystic_melody, player)) - add_rule_safe(world, LocationName.meteor_herd_3, player, + add_rule_safe(multiworld, LocationName.meteor_herd_3, player, lambda state: state.has(ItemName.knuckles_mystic_melody, player)) - add_rule_safe(world, LocationName.crazy_gadget_3, player, + add_rule_safe(multiworld, LocationName.crazy_gadget_3, 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_safe(world, LocationName.final_rush_3, player, + add_rule_safe(multiworld, LocationName.final_rush_3, 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_safe(world, LocationName.iron_gate_3, player, + add_rule_safe(multiworld, LocationName.iron_gate_3, player, lambda state: state.has(ItemName.eggman_mystic_melody, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.dry_lagoon_3, player, + add_rule_safe(multiworld, LocationName.dry_lagoon_3, player, lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_pick_nails, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.sand_ocean_3, player, + add_rule_safe(multiworld, LocationName.sand_ocean_3, player, lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.radical_highway_3, player, + add_rule_safe(multiworld, LocationName.radical_highway_3, player, lambda state: state.has(ItemName.shadow_mystic_melody, player)) - add_rule_safe(world, LocationName.egg_quarters_3, player, + add_rule_safe(multiworld, LocationName.egg_quarters_3, player, lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_pick_nails, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.lost_colony_3, player, + add_rule_safe(multiworld, LocationName.lost_colony_3, player, lambda state: state.has(ItemName.eggman_mystic_melody, player) and state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.weapons_bed_3, player, + add_rule_safe(multiworld, LocationName.weapons_bed_3, player, lambda state: state.has(ItemName.eggman_mystic_melody, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.security_hall_3, player, + add_rule_safe(multiworld, LocationName.security_hall_3, player, lambda state: state.has(ItemName.rouge_treasure_scope, player)) - add_rule_safe(world, LocationName.white_jungle_3, player, + add_rule_safe(multiworld, LocationName.white_jungle_3, player, lambda state: state.has(ItemName.shadow_air_shoes, player) and state.has(ItemName.shadow_mystic_melody, player)) - add_rule_safe(world, LocationName.sky_rail_3, player, + add_rule_safe(multiworld, LocationName.sky_rail_3, player, lambda state: state.has(ItemName.shadow_air_shoes, player) and state.has(ItemName.shadow_mystic_melody, player)) - add_rule_safe(world, LocationName.mad_space_3, player, + add_rule_safe(multiworld, LocationName.mad_space_3, player, lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.cosmic_wall_3, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_3, player, lambda state: state.has(ItemName.eggman_mystic_melody, player) and state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.final_chase_3, player, + add_rule_safe(multiworld, LocationName.final_chase_3, player, lambda state: state.has(ItemName.shadow_air_shoes, player) and state.has(ItemName.shadow_mystic_melody, player)) - add_rule_safe(world, LocationName.cannon_core_3, player, + add_rule_safe(multiworld, LocationName.cannon_core_3, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_mystic_melody, player) and state.has(ItemName.eggman_jet_engine, player) and @@ -227,52 +227,52 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int): state.has(ItemName.sonic_light_shoes, player)) # Mission 4 Upgrade Requirements - add_rule_safe(world, LocationName.metal_harbor_4, player, + add_rule_safe(multiworld, LocationName.metal_harbor_4, player, lambda state: state.has(ItemName.sonic_light_shoes, player)) - add_rule_safe(world, LocationName.pumpkin_hill_4, player, + add_rule_safe(multiworld, LocationName.pumpkin_hill_4, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule_safe(world, LocationName.mission_street_4, player, + add_rule_safe(multiworld, LocationName.mission_street_4, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.aquatic_mine_4, player, + add_rule_safe(multiworld, LocationName.aquatic_mine_4, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule_safe(world, LocationName.hidden_base_4, player, + add_rule_safe(multiworld, LocationName.hidden_base_4, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.pyramid_cave_4, player, + add_rule_safe(multiworld, LocationName.pyramid_cave_4, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.death_chamber_4, player, + add_rule_safe(multiworld, LocationName.death_chamber_4, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.eternal_engine_4, player, + add_rule_safe(multiworld, LocationName.eternal_engine_4, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule_safe(world, LocationName.meteor_herd_4, player, + add_rule_safe(multiworld, LocationName.meteor_herd_4, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.crazy_gadget_4, player, + add_rule_safe(multiworld, LocationName.crazy_gadget_4, 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_safe(world, LocationName.final_rush_4, player, + add_rule_safe(multiworld, LocationName.final_rush_4, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.egg_quarters_4, player, + add_rule_safe(multiworld, LocationName.egg_quarters_4, player, lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule_safe(world, LocationName.lost_colony_4, player, + add_rule_safe(multiworld, LocationName.lost_colony_4, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.weapons_bed_4, player, + add_rule_safe(multiworld, LocationName.weapons_bed_4, player, lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.security_hall_4, player, + add_rule_safe(multiworld, LocationName.security_hall_4, player, lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule_safe(world, LocationName.white_jungle_4, player, + add_rule_safe(multiworld, LocationName.white_jungle_4, player, lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule_safe(world, LocationName.mad_space_4, player, + add_rule_safe(multiworld, LocationName.mad_space_4, player, lambda state: state.has(ItemName.rouge_pick_nails, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.cosmic_wall_4, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_4, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cannon_core_4, player, + add_rule_safe(multiworld, LocationName.cannon_core_4, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.knuckles_hammer_gloves, player) and @@ -280,76 +280,76 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int): state.has(ItemName.sonic_bounce_bracelet, player)) # Mission 5 Upgrade Requirements - add_rule_safe(world, LocationName.city_escape_5, player, + add_rule_safe(multiworld, LocationName.city_escape_5, player, lambda state: state.has(ItemName.sonic_flame_ring, player) and state.has(ItemName.sonic_light_shoes, player)) - add_rule_safe(world, LocationName.wild_canyon_5, player, + add_rule_safe(multiworld, LocationName.wild_canyon_5, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_sunglasses, player)) - add_rule_safe(world, LocationName.metal_harbor_5, player, + add_rule_safe(multiworld, LocationName.metal_harbor_5, player, lambda state: state.has(ItemName.sonic_light_shoes, player)) - add_rule_safe(world, LocationName.green_forest_5, player, + add_rule_safe(multiworld, LocationName.green_forest_5, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.pumpkin_hill_5, player, + add_rule_safe(multiworld, LocationName.pumpkin_hill_5, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_sunglasses, player)) - add_rule_safe(world, LocationName.mission_street_5, player, + add_rule_safe(multiworld, LocationName.mission_street_5, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule_safe(world, LocationName.aquatic_mine_5, player, + add_rule_safe(multiworld, LocationName.aquatic_mine_5, player, lambda state: state.has(ItemName.knuckles_mystic_melody, player) and state.has(ItemName.knuckles_air_necklace, player) and state.has(ItemName.knuckles_sunglasses, player)) - add_rule_safe(world, LocationName.hidden_base_5, player, + add_rule_safe(multiworld, LocationName.hidden_base_5, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.pyramid_cave_5, player, + add_rule_safe(multiworld, LocationName.pyramid_cave_5, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.death_chamber_5, player, + add_rule_safe(multiworld, LocationName.death_chamber_5, player, lambda state: state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_mystic_melody, player) and state.has(ItemName.knuckles_air_necklace, player)) - add_rule_safe(world, LocationName.eternal_engine_5, player, + add_rule_safe(multiworld, LocationName.eternal_engine_5, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule_safe(world, LocationName.meteor_herd_5, player, + add_rule_safe(multiworld, LocationName.meteor_herd_5, player, lambda state: state.has(ItemName.knuckles_sunglasses, player)) - add_rule_safe(world, LocationName.crazy_gadget_5, player, + add_rule_safe(multiworld, LocationName.crazy_gadget_5, 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_safe(world, LocationName.final_rush_5, player, + add_rule_safe(multiworld, LocationName.final_rush_5, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.iron_gate_5, player, + add_rule_safe(multiworld, LocationName.iron_gate_5, player, lambda state: state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.dry_lagoon_5, player, + add_rule_safe(multiworld, LocationName.dry_lagoon_5, player, lambda state: state.has(ItemName.rouge_treasure_scope, player)) - add_rule_safe(world, LocationName.sand_ocean_5, player, + add_rule_safe(multiworld, LocationName.sand_ocean_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.egg_quarters_5, player, + add_rule_safe(multiworld, LocationName.egg_quarters_5, player, lambda state: state.has(ItemName.rouge_pick_nails, player) and 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(multiworld, LocationName.lost_colony_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.weapons_bed_5, player, + add_rule_safe(multiworld, LocationName.weapons_bed_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.security_hall_5, player, + add_rule_safe(multiworld, LocationName.security_hall_5, player, lambda state: state.has(ItemName.rouge_pick_nails, player) and state.has(ItemName.rouge_treasure_scope, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.white_jungle_5, player, + add_rule_safe(multiworld, LocationName.white_jungle_5, player, lambda state: state.has(ItemName.shadow_air_shoes, player) and state.has(ItemName.shadow_flame_ring, player)) - add_rule_safe(world, LocationName.mad_space_5, player, + add_rule_safe(multiworld, LocationName.mad_space_5, player, lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.cosmic_wall_5, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cannon_core_5, player, + add_rule_safe(multiworld, LocationName.cannon_core_5, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.knuckles_mystic_melody, player) and @@ -358,132 +358,132 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int): state.has(ItemName.sonic_bounce_bracelet, player)) # Upgrade Spot Upgrade Requirements - add_rule(world.get_location(LocationName.city_escape_upgrade, player), + add_rule(multiworld.get_location(LocationName.city_escape_upgrade, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and state.has(ItemName.sonic_flame_ring, player)) - add_rule(world.get_location(LocationName.wild_canyon_upgrade, player), + add_rule(multiworld.get_location(LocationName.wild_canyon_upgrade, player), lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule(world.get_location(LocationName.prison_lane_upgrade, player), + add_rule(multiworld.get_location(LocationName.prison_lane_upgrade, player), lambda state: state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.hidden_base_upgrade, player), + add_rule(multiworld.get_location(LocationName.hidden_base_upgrade, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.eternal_engine_upgrade, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_upgrade, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.meteor_herd_upgrade, player), + add_rule(multiworld.get_location(LocationName.meteor_herd_upgrade, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.crazy_gadget_upgrade, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_upgrade, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.final_rush_upgrade, player), + add_rule(multiworld.get_location(LocationName.final_rush_upgrade, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.iron_gate_upgrade, player), + add_rule(multiworld.get_location(LocationName.iron_gate_upgrade, player), lambda state: state.has(ItemName.eggman_large_cannon, player)) - add_rule(world.get_location(LocationName.dry_lagoon_upgrade, player), + add_rule(multiworld.get_location(LocationName.dry_lagoon_upgrade, player), lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule(world.get_location(LocationName.sand_ocean_upgrade, player), + add_rule(multiworld.get_location(LocationName.sand_ocean_upgrade, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.radical_highway_upgrade, player), + add_rule(multiworld.get_location(LocationName.radical_highway_upgrade, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule(world.get_location(LocationName.security_hall_upgrade, player), + add_rule(multiworld.get_location(LocationName.security_hall_upgrade, player), lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cosmic_wall_upgrade, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_upgrade, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) # Chao Key Upgrade Requirements - if world.keysanity[player]: - add_rule(world.get_location(LocationName.prison_lane_chao_1, player), + if world.options.keysanity: + add_rule(multiworld.get_location(LocationName.prison_lane_chao_1, player), lambda state: state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.mission_street_chao_1, player), + add_rule(multiworld.get_location(LocationName.mission_street_chao_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_chao_1, player), + add_rule(multiworld.get_location(LocationName.hidden_base_chao_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_chao_1, player), + add_rule(multiworld.get_location(LocationName.death_chamber_chao_1, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_chao_1, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_chao_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_chao_1, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_chao_1, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.cosmic_wall_chao_1, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_1, 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_chao_1, player), + add_rule(multiworld.get_location(LocationName.cannon_core_chao_1, 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_chao_2, player), + add_rule(multiworld.get_location(LocationName.prison_lane_chao_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.metal_harbor_chao_2, player), + add_rule(multiworld.get_location(LocationName.metal_harbor_chao_2, player), lambda state: state.has(ItemName.sonic_light_shoes, player)) - add_rule(world.get_location(LocationName.mission_street_chao_2, player), + add_rule(multiworld.get_location(LocationName.mission_street_chao_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_chao_2, player), + add_rule(multiworld.get_location(LocationName.hidden_base_chao_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.pyramid_cave_chao_2, player), + add_rule(multiworld.get_location(LocationName.pyramid_cave_chao_2, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.death_chamber_chao_2, player), + add_rule(multiworld.get_location(LocationName.death_chamber_chao_2, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_chao_2, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_chao_2, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_chao_2, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_chao_2, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.weapons_bed_chao_2, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_chao_2, 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_chao_2, player), + add_rule(multiworld.get_location(LocationName.white_jungle_chao_2, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule(world.get_location(LocationName.mad_space_chao_2, player), + add_rule(multiworld.get_location(LocationName.mad_space_chao_2, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cosmic_wall_chao_2, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_chao_2, player), + add_rule(multiworld.get_location(LocationName.cannon_core_chao_2, 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_chao_3, player), + add_rule(multiworld.get_location(LocationName.metal_harbor_chao_3, player), lambda state: state.has(ItemName.sonic_light_shoes, player)) - add_rule(world.get_location(LocationName.mission_street_chao_3, player), + add_rule(multiworld.get_location(LocationName.mission_street_chao_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.pyramid_cave_chao_3, player), + add_rule(multiworld.get_location(LocationName.pyramid_cave_chao_3, 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.death_chamber_chao_3, player), + add_rule(multiworld.get_location(LocationName.death_chamber_chao_3, 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_chao_3, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_chao_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_chao_3, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_chao_3, 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_chao_3, player), + add_rule(multiworld.get_location(LocationName.final_rush_chao_3, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.egg_quarters_chao_3, player), + add_rule(multiworld.get_location(LocationName.egg_quarters_chao_3, player), lambda state: state.has(ItemName.rouge_mystic_melody, player)) - add_rule(world.get_location(LocationName.lost_colony_chao_3, player), + add_rule(multiworld.get_location(LocationName.lost_colony_chao_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.weapons_bed_chao_3, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_chao_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule(world.get_location(LocationName.security_hall_chao_3, player), + add_rule(multiworld.get_location(LocationName.security_hall_chao_3, player), lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule(world.get_location(LocationName.white_jungle_chao_3, player), + add_rule(multiworld.get_location(LocationName.white_jungle_chao_3, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule(world.get_location(LocationName.mad_space_chao_3, player), + add_rule(multiworld.get_location(LocationName.mad_space_chao_3, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cosmic_wall_chao_3, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_chao_3, player), + add_rule(multiworld.get_location(LocationName.cannon_core_chao_3, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.knuckles_hammer_gloves, player) and @@ -491,804 +491,807 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int): state.has(ItemName.sonic_flame_ring, player)) # Pipe Upgrade Requirements - if world.whistlesanity[player].value == 1 or world.whistlesanity[player].value == 3: - add_rule(world.get_location(LocationName.mission_street_pipe_1, player), + if world.options.whistlesanity.value == 1 or world.options.whistlesanity.value == 3: + add_rule(multiworld.get_location(LocationName.mission_street_pipe_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_pipe_1, player), + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.sand_ocean_pipe_1, player), + add_rule(multiworld.get_location(LocationName.sand_ocean_pipe_1, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cosmic_wall_pipe_1, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_1, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.mission_street_pipe_2, player), + add_rule(multiworld.get_location(LocationName.cannon_core_pipe_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_pipe_2, player), + + add_rule(multiworld.get_location(LocationName.mission_street_pipe_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_pipe_2, player), + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_2, player), + lambda state: state.has(ItemName.tails_booster, player)) + add_rule(multiworld.get_location(LocationName.death_chamber_pipe_2, 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_pipe_2, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_pipe_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_pipe_2, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_pipe_2, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.sand_ocean_pipe_2, player), + add_rule(multiworld.get_location(LocationName.sand_ocean_pipe_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.lost_colony_pipe_2, player), + add_rule(multiworld.get_location(LocationName.lost_colony_pipe_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cosmic_wall_pipe_2, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_pipe_2, player), + add_rule(multiworld.get_location(LocationName.cannon_core_pipe_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.prison_lane_pipe_3, player), + add_rule(multiworld.get_location(LocationName.prison_lane_pipe_3, player), lambda state: state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.mission_street_pipe_3, player), + add_rule(multiworld.get_location(LocationName.mission_street_pipe_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_pipe_3, player), + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.pyramid_cave_pipe_3, player), + add_rule(multiworld.get_location(LocationName.pyramid_cave_pipe_3, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.death_chamber_pipe_3, player), + add_rule(multiworld.get_location(LocationName.death_chamber_pipe_3, 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_pipe_3, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_pipe_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_pipe_3, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_pipe_3, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and state.has(ItemName.sonic_mystic_melody, player)) - add_rule(world.get_location(LocationName.weapons_bed_pipe_3, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_pipe_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule(world.get_location(LocationName.white_jungle_pipe_3, player), + add_rule(multiworld.get_location(LocationName.white_jungle_pipe_3, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule(world.get_location(LocationName.mad_space_pipe_3, player), + add_rule(multiworld.get_location(LocationName.mad_space_pipe_3, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cosmic_wall_pipe_3, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_pipe_3, player), + add_rule(multiworld.get_location(LocationName.cannon_core_pipe_3, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.hidden_base_pipe_4, player), + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.pyramid_cave_pipe_4, player), + add_rule(multiworld.get_location(LocationName.pyramid_cave_pipe_4, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.eternal_engine_pipe_4, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_pipe_4, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_pipe_4, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_pipe_4, 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.weapons_bed_pipe_4, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_pipe_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.white_jungle_pipe_4, player), + add_rule(multiworld.get_location(LocationName.white_jungle_pipe_4, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule(world.get_location(LocationName.mad_space_pipe_4, player), + add_rule(multiworld.get_location(LocationName.mad_space_pipe_4, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cosmic_wall_pipe_4, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_4, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_pipe_4, player), + add_rule(multiworld.get_location(LocationName.cannon_core_pipe_4, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.hidden_base_pipe_5, player), + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_5, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.eternal_engine_pipe_5, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_pipe_5, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.weapons_bed_pipe_5, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_pipe_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.cosmic_wall_pipe_5, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_5, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_pipe_5, player), + add_rule(multiworld.get_location(LocationName.cannon_core_pipe_5, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.knuckles_air_necklace, player)) # Hidden Whistle Upgrade Requirements - if world.whistlesanity[player].value == 2 or world.whistlesanity[player].value == 3: - add_rule(world.get_location(LocationName.mission_street_hidden_3, player), + if world.options.whistlesanity.value == 2 or world.options.whistlesanity.value == 3: + add_rule(multiworld.get_location(LocationName.mission_street_hidden_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.mission_street_hidden_4, player), + add_rule(multiworld.get_location(LocationName.mission_street_hidden_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_hidden_1, player), + add_rule(multiworld.get_location(LocationName.death_chamber_hidden_1, player), lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.death_chamber_hidden_2, player), + add_rule(multiworld.get_location(LocationName.death_chamber_hidden_2, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.crazy_gadget_hidden_1, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_hidden_1, player), lambda state: state.has(ItemName.sonic_light_shoes, player)) - add_rule(world.get_location(LocationName.white_jungle_hidden_3, player), + add_rule(multiworld.get_location(LocationName.white_jungle_hidden_3, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule(world.get_location(LocationName.cannon_core_hidden_1, player), + add_rule(multiworld.get_location(LocationName.cannon_core_hidden_1, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player)) # Omochao Upgrade Requirements - if world.omosanity[player]: - add_rule(world.get_location(LocationName.eternal_engine_omo_1, player), + if world.options.omosanity: + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_omo_2, player), + add_rule(multiworld.get_location(LocationName.hidden_base_omo_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.pyramid_cave_omo_2, player), + add_rule(multiworld.get_location(LocationName.pyramid_cave_omo_2, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_2, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_2, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_2, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.radical_highway_omo_2, player), + add_rule(multiworld.get_location(LocationName.radical_highway_omo_2, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule(world.get_location(LocationName.weapons_bed_omo_2, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_omo_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.mission_street_omo_3, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_omo_3, player), + add_rule(multiworld.get_location(LocationName.hidden_base_omo_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.pyramid_cave_omo_3, player), + add_rule(multiworld.get_location(LocationName.pyramid_cave_omo_3, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_3, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.final_rush_omo_3, player), + add_rule(multiworld.get_location(LocationName.final_rush_omo_3, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.weapons_bed_omo_3, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_omo_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule(world.get_location(LocationName.metal_harbor_omo_4, player), + add_rule(multiworld.get_location(LocationName.metal_harbor_omo_4, player), lambda state: state.has(ItemName.sonic_light_shoes, player)) - add_rule(world.get_location(LocationName.mission_street_omo_4, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_omo_4, player), + add_rule(multiworld.get_location(LocationName.hidden_base_omo_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.pyramid_cave_omo_4, player), + add_rule(multiworld.get_location(LocationName.pyramid_cave_omo_4, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_4, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_4, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_4, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.mad_space_omo_4, player), + add_rule(multiworld.get_location(LocationName.mad_space_omo_4, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_4, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.metal_harbor_omo_5, player), + add_rule(multiworld.get_location(LocationName.metal_harbor_omo_5, player), lambda state: state.has(ItemName.sonic_light_shoes, player)) - add_rule(world.get_location(LocationName.mission_street_omo_5, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_5, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_5, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_5, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_5, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_5, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_5, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_5, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.white_jungle_omo_5, player), + add_rule(multiworld.get_location(LocationName.white_jungle_omo_5, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule(world.get_location(LocationName.mad_space_omo_5, player), + add_rule(multiworld.get_location(LocationName.mad_space_omo_5, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_5, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_5, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.mission_street_omo_6, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_6, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_6, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_6, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_6, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_6, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_6, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_6, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.lost_colony_omo_6, player), + add_rule(multiworld.get_location(LocationName.lost_colony_omo_6, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_6, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_6, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.mission_street_omo_7, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_7, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_7, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_7, player), lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_7, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_7, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_7, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_7, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.lost_colony_omo_7, player), + add_rule(multiworld.get_location(LocationName.lost_colony_omo_7, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_7, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_7, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.knuckles_air_necklace, player)) - add_rule(world.get_location(LocationName.mission_street_omo_8, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_8, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_8, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_8, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_8, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_8, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_8, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_8, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.lost_colony_omo_8, player), + add_rule(multiworld.get_location(LocationName.lost_colony_omo_8, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.security_hall_omo_8, player), + add_rule(multiworld.get_location(LocationName.security_hall_omo_8, player), lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_8, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_8, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.knuckles_air_necklace, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_9, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_9, player), lambda state: state.has(ItemName.knuckles_mystic_melody, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_9, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_9, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_9, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_9, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_9, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_9, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.knuckles_air_necklace, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_10, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_10, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_10, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_10, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_11, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_11, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_11, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_11, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_12, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_12, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_12, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_12, player), lambda state: state.has(ItemName.sonic_light_shoes, player) and state.has(ItemName.sonic_bounce_bracelet, player) and state.has(ItemName.sonic_flame_ring, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_13, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_13, player), lambda state: state.has(ItemName.sonic_light_shoes, player) and state.has(ItemName.sonic_bounce_bracelet, player) and state.has(ItemName.sonic_flame_ring, player)) # Gold Beetle Upgrade Requirements - if world.beetlesanity[player]: - add_rule(world.get_location(LocationName.mission_street_beetle, player), + if world.options.beetlesanity: + add_rule(multiworld.get_location(LocationName.mission_street_beetle, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_beetle, player), + add_rule(multiworld.get_location(LocationName.hidden_base_beetle, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.pyramid_cave_beetle, player), + add_rule(multiworld.get_location(LocationName.pyramid_cave_beetle, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.death_chamber_beetle, player), + add_rule(multiworld.get_location(LocationName.death_chamber_beetle, 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_beetle, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_beetle, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_beetle, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_beetle, 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.dry_lagoon_beetle, player), + add_rule(multiworld.get_location(LocationName.dry_lagoon_beetle, player), lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_pick_nails, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.lost_colony_beetle, player), + add_rule(multiworld.get_location(LocationName.lost_colony_beetle, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.white_jungle_beetle, player), + add_rule(multiworld.get_location(LocationName.white_jungle_beetle, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) - add_rule(world.get_location(LocationName.mad_space_beetle, player), + add_rule(multiworld.get_location(LocationName.mad_space_beetle, player), lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cosmic_wall_beetle, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_beetle, 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_beetle, player), + add_rule(multiworld.get_location(LocationName.cannon_core_beetle, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.knuckles_air_necklace, player)) # Animal Upgrade Requirements - if world.animalsanity[player]: - add_rule(world.get_location(LocationName.hidden_base_animal_2, player), + if world.options.animalsanity: + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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 @@ -1297,12 +1300,12 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int): (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), + add_rule(multiworld.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), + add_rule(multiworld.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 @@ -1310,12 +1313,12 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int): 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), + add_rule(multiworld.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), + add_rule(multiworld.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 @@ -1324,897 +1327,901 @@ def set_mission_upgrade_rules_standard(world: MultiWorld, player: int): 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), + add_rule(multiworld.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(multiworld: MultiWorld, world: World, player: int): # Mission 1 Upgrade Requirements - add_rule_safe(world, LocationName.pumpkin_hill_1, player, + add_rule_safe(multiworld, LocationName.pumpkin_hill_1, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule_safe(world, LocationName.mission_street_1, player, + add_rule_safe(multiworld, LocationName.mission_street_1, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.hidden_base_1, player, + add_rule_safe(multiworld, LocationName.hidden_base_1, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.death_chamber_1, player, + add_rule_safe(multiworld, LocationName.death_chamber_1, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.eternal_engine_1, player, + add_rule_safe(multiworld, LocationName.eternal_engine_1, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule_safe(world, LocationName.crazy_gadget_1, player, + add_rule_safe(multiworld, LocationName.crazy_gadget_1, player, lambda state: state.has(ItemName.sonic_light_shoes, player) and state.has(ItemName.sonic_flame_ring, player)) - add_rule_safe(world, LocationName.final_rush_1, player, + add_rule_safe(multiworld, LocationName.final_rush_1, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.egg_quarters_1, player, + add_rule_safe(multiworld, LocationName.egg_quarters_1, player, lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule_safe(world, LocationName.lost_colony_1, player, + add_rule_safe(multiworld, LocationName.lost_colony_1, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.weapons_bed_1, player, + add_rule_safe(multiworld, LocationName.weapons_bed_1, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cosmic_wall_1, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_1, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cannon_core_1, player, + add_rule_safe(multiworld, LocationName.cannon_core_1, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.knuckles_hammer_gloves, player)) # Mission 2 Upgrade Requirements - add_rule_safe(world, LocationName.mission_street_2, player, + add_rule_safe(multiworld, LocationName.mission_street_2, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.hidden_base_2, player, + add_rule_safe(multiworld, LocationName.hidden_base_2, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.death_chamber_2, player, + add_rule_safe(multiworld, LocationName.death_chamber_2, player, lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.eternal_engine_2, player, - lambda state: state.has(ItemName.tails_booster, player) and - state.has(ItemName.tails_bazooka, player)) + add_rule_safe(multiworld, LocationName.eternal_engine_2, player, + lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.lost_colony_2, player, - lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.weapons_bed_2, player, + add_rule_safe(multiworld, LocationName.weapons_bed_2, player, lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.cosmic_wall_2, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_2, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cannon_core_2, player, + add_rule_safe(multiworld, LocationName.cannon_core_2, player, lambda state: state.has(ItemName.tails_booster, player)) # Mission 3 Upgrade Requirements - add_rule_safe(world, LocationName.wild_canyon_3, player, + add_rule_safe(multiworld, LocationName.wild_canyon_3, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule_safe(world, LocationName.prison_lane_3, player, + add_rule_safe(multiworld, LocationName.prison_lane_3, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.mission_street_3, player, + add_rule_safe(multiworld, LocationName.mission_street_3, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.aquatic_mine_3, player, + add_rule_safe(multiworld, LocationName.aquatic_mine_3, player, lambda state: state.has(ItemName.knuckles_mystic_melody, player)) - add_rule_safe(world, LocationName.hidden_base_3, player, + add_rule_safe(multiworld, LocationName.hidden_base_3, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_mystic_melody, player)) - add_rule_safe(world, LocationName.death_chamber_3, player, + add_rule_safe(multiworld, LocationName.death_chamber_3, player, lambda state: state.has(ItemName.knuckles_mystic_melody, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.eternal_engine_3, player, + add_rule_safe(multiworld, LocationName.eternal_engine_3, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.meteor_herd_3, player, + add_rule_safe(multiworld, LocationName.meteor_herd_3, player, lambda state: state.has(ItemName.knuckles_mystic_melody, player)) - add_rule_safe(world, LocationName.crazy_gadget_3, player, + add_rule_safe(multiworld, LocationName.crazy_gadget_3, player, lambda state: state.has(ItemName.sonic_light_shoes, player) and state.has(ItemName.sonic_flame_ring, player)) - add_rule_safe(world, LocationName.final_rush_3, player, + add_rule_safe(multiworld, LocationName.final_rush_3, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.iron_gate_3, player, + add_rule_safe(multiworld, LocationName.iron_gate_3, player, lambda state: state.has(ItemName.eggman_mystic_melody, player) and state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.dry_lagoon_3, player, + add_rule_safe(multiworld, LocationName.dry_lagoon_3, player, lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_pick_nails, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.sand_ocean_3, player, + add_rule_safe(multiworld, LocationName.sand_ocean_3, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.egg_quarters_3, player, + add_rule_safe(multiworld, LocationName.egg_quarters_3, player, lambda state: state.has(ItemName.rouge_mystic_melody, player)) - add_rule_safe(world, LocationName.lost_colony_3, player, + add_rule_safe(multiworld, LocationName.lost_colony_3, player, lambda state: state.has(ItemName.eggman_mystic_melody, player) and state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.weapons_bed_3, player, + add_rule_safe(multiworld, LocationName.weapons_bed_3, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.mad_space_3, player, + add_rule_safe(multiworld, LocationName.mad_space_3, player, lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule_safe(world, LocationName.cosmic_wall_3, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_3, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cannon_core_3, player, + add_rule_safe(multiworld, LocationName.cannon_core_3, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.knuckles_hammer_gloves, player)) # Mission 4 Upgrade Requirements - add_rule_safe(world, LocationName.pumpkin_hill_4, player, + add_rule_safe(multiworld, LocationName.pumpkin_hill_4, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule_safe(world, LocationName.mission_street_4, player, + add_rule_safe(multiworld, LocationName.mission_street_4, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.hidden_base_4, player, + add_rule_safe(multiworld, LocationName.hidden_base_4, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.death_chamber_4, player, + add_rule_safe(multiworld, LocationName.death_chamber_4, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule_safe(world, LocationName.eternal_engine_4, player, + add_rule_safe(multiworld, LocationName.eternal_engine_4, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule_safe(world, LocationName.crazy_gadget_4, player, + add_rule_safe(multiworld, LocationName.crazy_gadget_4, player, lambda state: state.has(ItemName.sonic_light_shoes, player) and state.has(ItemName.sonic_flame_ring, player)) - add_rule_safe(world, LocationName.final_rush_4, player, + add_rule_safe(multiworld, LocationName.final_rush_4, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.egg_quarters_4, player, + add_rule_safe(multiworld, LocationName.egg_quarters_4, player, lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule_safe(world, LocationName.lost_colony_4, player, + add_rule_safe(multiworld, LocationName.lost_colony_4, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.weapons_bed_4, player, + add_rule_safe(multiworld, LocationName.weapons_bed_4, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cosmic_wall_4, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_4, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cannon_core_4, player, + add_rule_safe(multiworld, LocationName.cannon_core_4, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.knuckles_hammer_gloves, player)) # Mission 5 Upgrade Requirements - add_rule_safe(world, LocationName.city_escape_5, player, + add_rule_safe(multiworld, LocationName.city_escape_5, player, lambda state: state.has(ItemName.sonic_flame_ring, player)) - add_rule_safe(world, LocationName.wild_canyon_5, player, + add_rule_safe(multiworld, LocationName.wild_canyon_5, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule_safe(world, LocationName.pumpkin_hill_5, player, + add_rule_safe(multiworld, LocationName.pumpkin_hill_5, player, lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule_safe(world, LocationName.mission_street_5, player, + add_rule_safe(multiworld, LocationName.mission_street_5, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.aquatic_mine_5, player, + add_rule_safe(multiworld, LocationName.aquatic_mine_5, player, lambda state: state.has(ItemName.knuckles_mystic_melody, player)) - add_rule_safe(world, LocationName.hidden_base_5, player, + add_rule_safe(multiworld, LocationName.hidden_base_5, player, lambda state: state.has(ItemName.tails_booster, player)) - add_rule_safe(world, LocationName.death_chamber_5, player, + add_rule_safe(multiworld, LocationName.death_chamber_5, player, lambda state: state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_mystic_melody, player)) - add_rule_safe(world, LocationName.eternal_engine_5, player, + add_rule_safe(multiworld, LocationName.eternal_engine_5, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule_safe(world, LocationName.crazy_gadget_5, player, + add_rule_safe(multiworld, LocationName.crazy_gadget_5, 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_safe(world, LocationName.final_rush_5, player, + add_rule_safe(multiworld, LocationName.final_rush_5, player, lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule_safe(world, LocationName.iron_gate_5, player, + add_rule_safe(multiworld, LocationName.iron_gate_5, player, lambda state: state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.dry_lagoon_5, player, + add_rule_safe(multiworld, LocationName.dry_lagoon_5, player, lambda state: state.has(ItemName.rouge_treasure_scope, player)) - add_rule_safe(world, LocationName.sand_ocean_5, player, + add_rule_safe(multiworld, LocationName.sand_ocean_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.egg_quarters_5, player, + add_rule_safe(multiworld, LocationName.egg_quarters_5, player, lambda state: state.has(ItemName.rouge_pick_nails, player) and state.has(ItemName.rouge_treasure_scope, player)) - add_rule_safe(world, LocationName.lost_colony_5, player, + add_rule_safe(multiworld, LocationName.lost_colony_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player) and state.has(ItemName.eggman_large_cannon, player)) - add_rule_safe(world, LocationName.weapons_bed_5, player, + add_rule_safe(multiworld, LocationName.weapons_bed_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.security_hall_5, player, + add_rule_safe(multiworld, LocationName.security_hall_5, player, lambda state: state.has(ItemName.rouge_treasure_scope, player)) - add_rule_safe(world, LocationName.cosmic_wall_5, player, + add_rule_safe(multiworld, LocationName.cosmic_wall_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule_safe(world, LocationName.cannon_core_5, player, + add_rule_safe(multiworld, LocationName.cannon_core_5, player, lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.knuckles_mystic_melody, player) and state.has(ItemName.knuckles_hammer_gloves, player)) # Upgrade Spot Upgrade Requirements - add_rule(world.get_location(LocationName.city_escape_upgrade, player), + add_rule(multiworld.get_location(LocationName.city_escape_upgrade, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player) and state.has(ItemName.sonic_flame_ring, player)) - add_rule(world.get_location(LocationName.wild_canyon_upgrade, player), + add_rule(multiworld.get_location(LocationName.wild_canyon_upgrade, player), lambda state: state.has(ItemName.knuckles_shovel_claws, player)) - add_rule(world.get_location(LocationName.prison_lane_upgrade, player), + add_rule(multiworld.get_location(LocationName.prison_lane_upgrade, player), lambda state: state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.hidden_base_upgrade, player), + add_rule(multiworld.get_location(LocationName.hidden_base_upgrade, player), lambda state: state.has(ItemName.tails_booster, player) and (state.has(ItemName.tails_bazooka, player) or state.has(ItemName.tails_mystic_melody, player))) - add_rule(world.get_location(LocationName.eternal_engine_upgrade, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_upgrade, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.meteor_herd_upgrade, player), + add_rule(multiworld.get_location(LocationName.meteor_herd_upgrade, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.final_rush_upgrade, player), + add_rule(multiworld.get_location(LocationName.final_rush_upgrade, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.iron_gate_upgrade, player), + add_rule(multiworld.get_location(LocationName.iron_gate_upgrade, player), lambda state: state.has(ItemName.eggman_jet_engine, player) or state.has(ItemName.eggman_large_cannon, player)) - add_rule(world.get_location(LocationName.dry_lagoon_upgrade, player), + add_rule(multiworld.get_location(LocationName.dry_lagoon_upgrade, player), lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule(world.get_location(LocationName.sand_ocean_upgrade, player), + add_rule(multiworld.get_location(LocationName.sand_ocean_upgrade, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.security_hall_upgrade, player), + add_rule(multiworld.get_location(LocationName.security_hall_upgrade, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cosmic_wall_upgrade, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_upgrade, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) # Chao Key Upgrade Requirements - if world.keysanity[player]: - add_rule(world.get_location(LocationName.prison_lane_chao_1, player), + if world.options.keysanity: + add_rule(multiworld.get_location(LocationName.prison_lane_chao_1, player), lambda state: state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.mission_street_chao_1, player), + add_rule(multiworld.get_location(LocationName.mission_street_chao_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_chao_1, player), + add_rule(multiworld.get_location(LocationName.hidden_base_chao_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_chao_1, player), + add_rule(multiworld.get_location(LocationName.death_chamber_chao_1, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_chao_1, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_chao_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.cosmic_wall_chao_1, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_1, 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_chao_1, player), + add_rule(multiworld.get_location(LocationName.cannon_core_chao_1, 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_chao_2, player), + add_rule(multiworld.get_location(LocationName.prison_lane_chao_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.mission_street_chao_2, player), + add_rule(multiworld.get_location(LocationName.mission_street_chao_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_chao_2, player), + add_rule(multiworld.get_location(LocationName.hidden_base_chao_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_chao_2, player), + add_rule(multiworld.get_location(LocationName.death_chamber_chao_2, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_chao_2, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_chao_2, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_chao_2, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_chao_2, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.weapons_bed_chao_2, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_chao_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cosmic_wall_chao_2, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_chao_2, player), + add_rule(multiworld.get_location(LocationName.cannon_core_chao_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.mission_street_chao_3, player), + add_rule(multiworld.get_location(LocationName.mission_street_chao_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_chao_3, player), + add_rule(multiworld.get_location(LocationName.death_chamber_chao_3, 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_chao_3, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_chao_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.crazy_gadget_chao_3, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_chao_3, 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_chao_3, player), + add_rule(multiworld.get_location(LocationName.final_rush_chao_3, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.egg_quarters_chao_3, player), + add_rule(multiworld.get_location(LocationName.egg_quarters_chao_3, player), lambda state: state.has(ItemName.rouge_mystic_melody, player)) - add_rule(world.get_location(LocationName.lost_colony_chao_3, player), + add_rule(multiworld.get_location(LocationName.lost_colony_chao_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.weapons_bed_chao_3, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_chao_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.security_hall_chao_3, player), + add_rule(multiworld.get_location(LocationName.security_hall_chao_3, player), lambda state: state.has(ItemName.rouge_pick_nails, player)) - add_rule(world.get_location(LocationName.cosmic_wall_chao_3, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_chao_3, player), + add_rule(multiworld.get_location(LocationName.cannon_core_chao_3, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.knuckles_hammer_gloves, player) and state.has(ItemName.sonic_flame_ring, player)) # Pipe Upgrade Requirements - if world.whistlesanity[player].value == 1 or world.whistlesanity[player].value == 3: - add_rule(world.get_location(LocationName.hidden_base_pipe_1, player), + if world.options.whistlesanity.value == 1 or world.options.whistlesanity.value == 3: + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.cosmic_wall_pipe_1, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_1, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.hidden_base_pipe_2, player), + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_pipe_2, player), + add_rule(multiworld.get_location(LocationName.death_chamber_pipe_2, 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_pipe_2, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_pipe_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.lost_colony_pipe_2, player), + add_rule(multiworld.get_location(LocationName.lost_colony_pipe_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cosmic_wall_pipe_2, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_pipe_2, player), + add_rule(multiworld.get_location(LocationName.cannon_core_pipe_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.prison_lane_pipe_3, player), + add_rule(multiworld.get_location(LocationName.prison_lane_pipe_3, player), lambda state: state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.mission_street_pipe_3, player), + add_rule(multiworld.get_location(LocationName.mission_street_pipe_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_pipe_3, player), + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_pipe_3, player), + add_rule(multiworld.get_location(LocationName.death_chamber_pipe_3, 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_pipe_3, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_pipe_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.weapons_bed_pipe_3, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_pipe_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cosmic_wall_pipe_3, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_pipe_3, player), + add_rule(multiworld.get_location(LocationName.cannon_core_pipe_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_pipe_4, player), + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.eternal_engine_pipe_4, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_pipe_4, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_pipe_4, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_pipe_4, player), lambda state: state.has(ItemName.sonic_light_shoes, player) and state.has(ItemName.sonic_flame_ring, player)) - add_rule(world.get_location(LocationName.weapons_bed_pipe_4, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_pipe_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.cosmic_wall_pipe_4, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_4, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_pipe_4, player), + add_rule(multiworld.get_location(LocationName.cannon_core_pipe_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_pipe_5, player), + add_rule(multiworld.get_location(LocationName.hidden_base_pipe_5, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.eternal_engine_pipe_5, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_pipe_5, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.weapons_bed_pipe_5, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_pipe_5, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cosmic_wall_pipe_5, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_5, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_pipe_5, player), + add_rule(multiworld.get_location(LocationName.cannon_core_pipe_5, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.knuckles_hammer_gloves, player)) # Hidden Whistle Upgrade Requirements - if world.whistlesanity[player].value == 2 or world.whistlesanity[player].value == 3: - add_rule(world.get_location(LocationName.mission_street_hidden_3, player), + if world.options.whistlesanity.value == 2 or world.options.whistlesanity.value == 3: + add_rule(multiworld.get_location(LocationName.mission_street_hidden_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.mission_street_hidden_4, player), + add_rule(multiworld.get_location(LocationName.mission_street_hidden_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_hidden_1, player), + add_rule(multiworld.get_location(LocationName.death_chamber_hidden_1, player), lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.death_chamber_hidden_2, player), + add_rule(multiworld.get_location(LocationName.death_chamber_hidden_2, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.cannon_core_hidden_1, player), + add_rule(multiworld.get_location(LocationName.cannon_core_hidden_1, player), lambda state: state.has(ItemName.tails_booster, player)) # Omochao Upgrade Requirements - if world.omosanity[player]: - add_rule(world.get_location(LocationName.eternal_engine_omo_1, player), + if world.options.omosanity: + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_1, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.hidden_base_omo_2, player), + add_rule(multiworld.get_location(LocationName.hidden_base_omo_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_2, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_2, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_2, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_2, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.weapons_bed_omo_2, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_omo_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player) or state.has(ItemName.eggman_large_cannon, player)) - add_rule(world.get_location(LocationName.hidden_base_omo_3, player), + add_rule(multiworld.get_location(LocationName.hidden_base_omo_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_3, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_3, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.final_rush_omo_3, player), + add_rule(multiworld.get_location(LocationName.final_rush_omo_3, player), lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) - add_rule(world.get_location(LocationName.weapons_bed_omo_3, player), + add_rule(multiworld.get_location(LocationName.weapons_bed_omo_3, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.hidden_base_omo_4, player), + add_rule(multiworld.get_location(LocationName.hidden_base_omo_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_4, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_4, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_4, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_4, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_4, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.mission_street_omo_5, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_5, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_5, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_5, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_5, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_5, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_5, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_5, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.mission_street_omo_6, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_6, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_6, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_6, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_6, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_6, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.lost_colony_omo_6, player), + add_rule(multiworld.get_location(LocationName.lost_colony_omo_6, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_6, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_6, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.mission_street_omo_7, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_7, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_7, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_7, player), lambda state: state.has(ItemName.knuckles_shovel_claws, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_7, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_7, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.lost_colony_omo_7, player), + add_rule(multiworld.get_location(LocationName.lost_colony_omo_7, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_7, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_7, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.mission_street_omo_8, player), + add_rule(multiworld.get_location(LocationName.mission_street_omo_8, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_8, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_8, player), lambda state: state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_8, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_8, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.lost_colony_omo_8, player), + add_rule(multiworld.get_location(LocationName.lost_colony_omo_8, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.security_hall_omo_8, player), + add_rule(multiworld.get_location(LocationName.security_hall_omo_8, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_8, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_8, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.death_chamber_omo_9, player), + add_rule(multiworld.get_location(LocationName.death_chamber_omo_9, player), lambda state: state.has(ItemName.knuckles_mystic_melody, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_9, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_9, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.cannon_core_omo_9, player), + add_rule(multiworld.get_location(LocationName.cannon_core_omo_9, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.knuckles_hammer_gloves, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_10, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_10, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_11, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_11, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.eternal_engine_omo_12, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_omo_12, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_12, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_12, player), lambda state: state.has(ItemName.sonic_light_shoes, player) and state.has(ItemName.sonic_flame_ring, player)) - add_rule(world.get_location(LocationName.crazy_gadget_omo_13, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_omo_13, player), lambda state: state.has(ItemName.sonic_light_shoes, player) and state.has(ItemName.sonic_flame_ring, player)) # Gold Beetle Upgrade Requirements - if world.beetlesanity[player]: - add_rule(world.get_location(LocationName.hidden_base_beetle, player), + if world.options.beetlesanity: + add_rule(multiworld.get_location(LocationName.hidden_base_beetle, player), lambda state: state.has(ItemName.tails_booster, player)) - add_rule(world.get_location(LocationName.death_chamber_beetle, player), + add_rule(multiworld.get_location(LocationName.death_chamber_beetle, 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_beetle, player), + add_rule(multiworld.get_location(LocationName.eternal_engine_beetle, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.tails_bazooka, player)) - add_rule(world.get_location(LocationName.crazy_gadget_beetle, player), + add_rule(multiworld.get_location(LocationName.crazy_gadget_beetle, player), lambda state: state.has(ItemName.sonic_light_shoes, player) and state.has(ItemName.sonic_flame_ring, player)) - add_rule(world.get_location(LocationName.dry_lagoon_beetle, player), + add_rule(multiworld.get_location(LocationName.dry_lagoon_beetle, player), lambda state: state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_pick_nails, player) and state.has(ItemName.rouge_iron_boots, player)) - add_rule(world.get_location(LocationName.lost_colony_beetle, player), + add_rule(multiworld.get_location(LocationName.lost_colony_beetle, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(world.get_location(LocationName.cosmic_wall_beetle, player), + add_rule(multiworld.get_location(LocationName.cosmic_wall_beetle, 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_beetle, player), + add_rule(multiworld.get_location(LocationName.cannon_core_beetle, player), lambda state: state.has(ItemName.tails_booster, player) and 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), + if world.options.animalsanity: + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.get_location(LocationName.lost_colony_animal_9, player), + lambda state: state.has(ItemName.eggman_jet_engine, player) or + state.has(ItemName.eggman_large_cannon, player)) + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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), + add_rule(multiworld.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(multiworld: MultiWorld, player: int, gate_bosses: typing.Dict[int, int]): for x in range(len(gate_bosses)): if boss_has_requirement(gate_bosses[x + 1]): - add_rule(world.get_location(boss_gate_set[x], player), + add_rule(multiworld.get_location(boss_gate_set[x], player), lambda state: state.has(ItemName.knuckles_shovel_claws, player)) -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]): +def set_rules(multiworld: MultiWorld, world: World, 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], black_market_costs: typing.Dict[int, int]): # Mission Progression Rules (Mission 1 begets Mission 2, etc.) - set_mission_progress_rules(world, player, mission_map, mission_count_map) + set_mission_progress_rules(multiworld, player, mission_map, mission_count_map) - if world.goal[player].value != 3: + if world.options.goal.value != 3: # Upgrade Requirements for each mission location - if world.logic_difficulty[player].value == 0: - set_mission_upgrade_rules_standard(world, player) - elif world.logic_difficulty[player].value == 1: - set_mission_upgrade_rules_hard(world, player) + if world.options.logic_difficulty.value == 0: + set_mission_upgrade_rules_standard(multiworld, world, player) + elif world.options.logic_difficulty.value == 1: + set_mission_upgrade_rules_hard(multiworld, world, player) - if world.goal[player] in [4, 5, 6]: + for i in range(world.options.black_market_slots.value): + add_rule(multiworld.get_location(LocationName.chao_black_market_base + str(i + 1), player), + lambda state, i=i: (state.has(ItemName.market_token, player, black_market_costs[i]))) + + if world.options.goal 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), + add_rule(multiworld.get_location("Boss Rush - " + str(i + 1), player), lambda state: (state.has(ItemName.knuckles_shovel_claws, player))) # Upgrade Requirements for each boss gate - set_boss_gate_rules(world, player, gate_bosses) + set_boss_gate_rules(multiworld, player, gate_bosses) - world.completion_condition[player] = lambda state: state.has(ItemName.maria, player) + multiworld.completion_condition[player] = lambda state: state.has(ItemName.maria, player) diff --git a/worlds/sa2b/__init__.py b/worlds/sa2b/__init__.py index 496d18fa..4ee03dce 100644 --- a/worlds/sa2b/__init__.py +++ b/worlds/sa2b/__init__.py @@ -1,14 +1,18 @@ import typing import math +import logging from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification -from .Items import SA2BItem, ItemData, item_table, upgrades_table, emeralds_table, junk_table, trap_table, item_groups -from .Locations import SA2BLocation, all_locations, setup_locations +from .Items import SA2BItem, ItemData, item_table, upgrades_table, emeralds_table, junk_table, trap_table, item_groups, \ + eggs_table, fruits_table, seeds_table, hats_table, animals_table, chaos_drives_table +from .Locations import SA2BLocation, all_locations, setup_locations, chao_animal_event_location_table, black_market_location_table from .Options import sa2b_options from .Regions import create_regions, shuffleable_regions, connect_regions, LevelGate, gate_0_whitelist_regions, \ gate_0_blacklist_regions from .Rules import set_rules from .Names import ItemName, LocationName +from .AestheticData import chao_name_conversion, sample_chao_names, totally_real_item_names, \ + all_exits, all_destinations, multi_rooms, single_rooms, room_to_exits_map, exit_to_room_map, valid_kindergarten_exits from worlds.AutoWorld import WebWorld, World 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 @@ -52,7 +56,7 @@ class SA2BWorld(World): game: str = "Sonic Adventure 2 Battle" option_definitions = sa2b_options topology_present = False - data_version = 6 + data_version = 7 item_name_groups = item_groups item_name_to_id = {name: data.code for name, data in item_table.items()} @@ -60,8 +64,6 @@ class SA2BWorld(World): location_table: typing.Dict[str, int] - music_map: typing.Dict[int, int] - voice_map: typing.Dict[int, int] mission_map: typing.Dict[int, int] mission_count_map: typing.Dict[int, int] emblems_for_cannons_core: int @@ -69,138 +71,126 @@ class SA2BWorld(World): gate_costs: typing.Dict[int, int] gate_bosses: typing.Dict[int, int] boss_rush_map: typing.Dict[int, int] + black_market_costs: typing.Dict[int, int] + web = SA2BWeb() - def _get_slot_data(self): + def fill_slot_data(self) -> dict: return { - "ModVersion": 202, - "Goal": self.multiworld.goal[self.player].value, - "MusicMap": self.music_map, - "VoiceMap": self.voice_map, + "ModVersion": 203, + "Goal": self.options.goal.value, + "MusicMap": self.generate_music_data(), + "VoiceMap": self.generate_voice_data(), + "DefaultEggMap": self.generate_chao_egg_data(), + "DefaultChaoNameMap": self.generate_chao_name_data(), "MissionMap": self.mission_map, "MissionCountMap": self.mission_count_map, - "MusicShuffle": self.multiworld.music_shuffle[self.player].value, - "Narrator": self.multiworld.narrator[self.player].value, - "MinigameTrapDifficulty": self.multiworld.minigame_trap_difficulty[self.player].value, - "RingLoss": self.multiworld.ring_loss[self.player].value, - "RingLink": self.multiworld.ring_link[self.player].value, - "RequiredRank": self.multiworld.required_rank[self.player].value, - "ChaoKeys": self.multiworld.keysanity[self.player].value, - "Whistlesanity": self.multiworld.whistlesanity[self.player].value, - "GoldBeetles": self.multiworld.beetlesanity[self.player].value, - "OmochaoChecks": self.multiworld.omosanity[self.player].value, - "AnimalChecks": self.multiworld.animalsanity[self.player].value, - "KartRaceChecks": self.multiworld.kart_race_checks[self.player].value, - "ChaoRaceChecks": self.multiworld.chao_race_checks[self.player].value, - "ChaoGardenDifficulty": self.multiworld.chao_garden_difficulty[self.player].value, - "DeathLink": self.multiworld.death_link[self.player].value, - "EmblemPercentageForCannonsCore": self.multiworld.emblem_percentage_for_cannons_core[self.player].value, - "RequiredCannonsCoreMissions": self.multiworld.required_cannons_core_missions[self.player].value, - "NumberOfLevelGates": self.multiworld.number_of_level_gates[self.player].value, - "LevelGateDistribution": self.multiworld.level_gate_distribution[self.player].value, + "MusicShuffle": self.options.music_shuffle.value, + "Narrator": self.options.narrator.value, + "MinigameTrapDifficulty": self.options.minigame_trap_difficulty.value, + "RingLoss": self.options.ring_loss.value, + "RingLink": self.options.ring_link.value, + "RequiredRank": self.options.required_rank.value, + "ChaoKeys": self.options.keysanity.value, + "Whistlesanity": self.options.whistlesanity.value, + "GoldBeetles": self.options.beetlesanity.value, + "OmochaoChecks": self.options.omosanity.value, + "AnimalChecks": self.options.animalsanity.value, + "KartRaceChecks": self.options.kart_race_checks.value, + "ChaoStadiumChecks": self.options.chao_stadium_checks.value, + "ChaoRaceDifficulty": self.options.chao_race_difficulty.value, + "ChaoKarateDifficulty": self.options.chao_karate_difficulty.value, + "ChaoStats": self.options.chao_stats.value, + "ChaoStatsFrequency": self.options.chao_stats_frequency.value, + "ChaoStatsStamina": self.options.chao_stats_stamina.value, + "ChaoStatsHidden": self.options.chao_stats_hidden.value, + "ChaoAnimalParts": self.options.chao_animal_parts.value, + "ChaoKindergarten": self.options.chao_kindergarten.value, + "BlackMarketSlots": self.options.black_market_slots.value, + "BlackMarketData": self.generate_black_market_data(), + "BlackMarketUnlockCosts": self.black_market_costs, + "BlackMarketUnlockSetting": self.options.black_market_unlock_costs.value, + "ChaoERLayout": self.generate_er_layout(), + "DeathLink": self.options.death_link.value, + "EmblemPercentageForCannonsCore": self.options.emblem_percentage_for_cannons_core.value, + "RequiredCannonsCoreMissions": self.options.required_cannons_core_missions.value, + "NumberOfLevelGates": self.options.number_of_level_gates.value, + "LevelGateDistribution": self.options.level_gate_distribution.value, "EmblemsForCannonsCore": self.emblems_for_cannons_core, "RegionEmblemMap": self.region_emblem_map, "GateCosts": self.gate_costs, "GateBosses": self.gate_bosses, "BossRushMap": self.boss_rush_map, + "PlayerNum": self.player, } - def _create_items(self, name: str): - data = item_table[name] - return [self.create_item(name) for _ in range(data.quantity)] - - def fill_slot_data(self) -> dict: - slot_data = self._get_slot_data() - slot_data["MusicMap"] = self.music_map - for option_name in sa2b_options: - option = getattr(self.multiworld, option_name)[self.player] - slot_data[option_name] = option.value - - return slot_data - - def get_levels_per_gate(self) -> list: - levels_per_gate = list() - max_gate_index = self.multiworld.number_of_level_gates[self.player] - average_level_count = 30 / (max_gate_index + 1) - levels_added = 0 - - for i in range(max_gate_index + 1): - levels_per_gate.append(average_level_count) - levels_added += average_level_count - additional_count_iterator = 0 - while levels_added < 30: - levels_per_gate[additional_count_iterator] += 1 - levels_added += 1 - additional_count_iterator += 1 if additional_count_iterator < max_gate_index else -max_gate_index - - if self.multiworld.level_gate_distribution[self.player] == 0 or self.multiworld.level_gate_distribution[self.player] == 2: - early_distribution = self.multiworld.level_gate_distribution[self.player] == 0 - levels_to_distribute = 5 - gate_index_offset = 0 - while levels_to_distribute > 0: - if levels_per_gate[0 + gate_index_offset] == 1 or \ - levels_per_gate[max_gate_index - gate_index_offset] == 1: - break - if early_distribution: - levels_per_gate[0 + gate_index_offset] += 1 - levels_per_gate[max_gate_index - gate_index_offset] -= 1 - else: - levels_per_gate[0 + gate_index_offset] -= 1 - levels_per_gate[max_gate_index - gate_index_offset] += 1 - gate_index_offset += 1 - if gate_index_offset > math.floor(max_gate_index / 2): - gate_index_offset = 0 - levels_to_distribute -= 1 - - return levels_per_gate - def generate_early(self): - if self.multiworld.goal[self.player].value == 3: + if self.options.goal.value == 3: # Turn off everything else for Grand Prix goal - self.multiworld.number_of_level_gates[self.player].value = 0 - self.multiworld.emblem_percentage_for_cannons_core[self.player].value = 0 - self.multiworld.junk_fill_percentage[self.player].value = 100 - self.multiworld.trap_fill_percentage[self.player].value = 100 - self.multiworld.omochao_trap_weight[self.player].value = 0 - self.multiworld.timestop_trap_weight[self.player].value = 0 - self.multiworld.confusion_trap_weight[self.player].value = 0 - self.multiworld.tiny_trap_weight[self.player].value = 0 - self.multiworld.gravity_trap_weight[self.player].value = 0 - self.multiworld.ice_trap_weight[self.player].value = 0 - self.multiworld.slow_trap_weight[self.player].value = 0 + self.options.number_of_level_gates.value = 0 + self.options.emblem_percentage_for_cannons_core.value = 0 - 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 + self.options.chao_race_difficulty.value = 0 + self.options.chao_karate_difficulty.value = 0 + self.options.chao_stats.value = 0 + self.options.chao_animal_parts.value = 0 + self.options.chao_kindergarten.value = 0 + self.options.black_market_slots.value = 0 + + self.options.junk_fill_percentage.value = 100 + self.options.trap_fill_percentage.value = 100 + self.options.omochao_trap_weight.value = 0 + self.options.timestop_trap_weight.value = 0 + self.options.confusion_trap_weight.value = 0 + self.options.tiny_trap_weight.value = 0 + self.options.gravity_trap_weight.value = 0 + self.options.ice_trap_weight.value = 0 + self.options.slow_trap_weight.value = 0 + self.options.cutscene_trap_weight.value = 0 + + valid_trap_weights = self.options.exposition_trap_weight.value + \ + self.options.reverse_trap_weight.value + \ + self.options.pong_trap_weight.value if valid_trap_weights == 0: - 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.options.exposition_trap_weight.value = 4 + self.options.reverse_trap_weight.value = 4 + self.options.pong_trap_weight.value = 4 - if self.multiworld.kart_race_checks[self.player].value == 0: - self.multiworld.kart_race_checks[self.player].value = 2 + if self.options.kart_race_checks.value == 0: + self.options.kart_race_checks.value = 2 self.gate_bosses = {} self.boss_rush_map = {} else: - self.gate_bosses = get_gate_bosses(self.multiworld, self.player) - self.boss_rush_map = get_boss_rush_bosses(self.multiworld, self.player) + self.gate_bosses = get_gate_bosses(self.multiworld, self) + self.boss_rush_map = get_boss_rush_bosses(self.multiworld, self) def create_regions(self): - self.mission_map = get_mission_table(self.multiworld, self.player) - self.mission_count_map = get_mission_count_table(self.multiworld, self.player) + self.mission_map = get_mission_table(self.multiworld, self, self.player) + self.mission_count_map = get_mission_count_table(self.multiworld, self, self.player) - self.location_table = setup_locations(self.multiworld, self.player, self.mission_map, self.mission_count_map) - create_regions(self.multiworld, self.player, self.location_table) + self.location_table = setup_locations(self, self.player, self.mission_map, self.mission_count_map) + create_regions(self.multiworld, self, self.player, self.location_table) # Not Generate Basic - if self.multiworld.goal[self.player].value in [0, 2, 4, 5, 6]: + self.black_market_costs = dict() + + if self.options.goal.value in [0, 2, 4, 5, 6]: 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.options.goal.value == 1: self.multiworld.get_location(LocationName.green_hill, self.player).place_locked_item(self.create_item(ItemName.maria)) - elif self.multiworld.goal[self.player].value == 3: + elif self.options.goal.value == 3: self.multiworld.get_location(LocationName.grand_prix, self.player).place_locked_item(self.create_item(ItemName.maria)) + elif self.options.goal.value == 7: + self.multiworld.get_location(LocationName.chaos_chao, self.player).place_locked_item(self.create_item(ItemName.maria)) + + for animal_name in chao_animal_event_location_table.keys(): + animal_region = self.multiworld.get_region(animal_name, self.player) + animal_event_location = SA2BLocation(self.player, animal_name, None, animal_region) + animal_region.locations.append(animal_event_location) + animal_event_item = SA2BItem(animal_name, ItemClassification.progression, None, self.player) + self.multiworld.get_location(animal_name, self.player).place_locked_item(animal_event_item) itempool: typing.List[SA2BItem] = [] @@ -208,28 +198,40 @@ class SA2BWorld(World): total_required_locations = len(self.location_table) total_required_locations -= 1; # Locked Victory Location - if self.multiworld.goal[self.player].value != 3: + if self.options.goal.value != 3: # Fill item pool with all required items for item in {**upgrades_table}: - itempool += [self.create_item(item, False, self.multiworld.goal[self.player].value)] + itempool += [self.create_item(item, False, self.options.goal.value)] - if self.multiworld.goal[self.player].value in [1, 2, 6]: + if self.options.goal.value in [1, 2, 6]: # Some flavor of Chaos Emerald Hunt for item in {**emeralds_table}: - itempool += self._create_items(item) + itempool.append(self.create_item(item)) + + # Black Market + itempool += [self.create_item(ItemName.market_token) for _ in range(self.options.black_market_slots.value)] + + black_market_unlock_mult = 1.0 + if self.options.black_market_unlock_costs.value == 0: + black_market_unlock_mult = 0.5 + elif self.options.black_market_unlock_costs.value == 1: + black_market_unlock_mult = 0.75 + + for i in range(self.options.black_market_slots.value): + self.black_market_costs[i] = math.floor((i + 1) * black_market_unlock_mult) # Cap at player-specified Emblem count raw_emblem_count = total_required_locations - len(itempool) - total_emblem_count = min(raw_emblem_count, self.multiworld.max_emblem_cap[self.player].value) + total_emblem_count = min(raw_emblem_count, self.options.max_emblem_cap.value) extra_junk_count = raw_emblem_count - total_emblem_count self.emblems_for_cannons_core = math.floor( - total_emblem_count * (self.multiworld.emblem_percentage_for_cannons_core[self.player].value / 100.0)) + total_emblem_count * (self.options.emblem_percentage_for_cannons_core.value / 100.0)) gate_cost_mult = 1.0 - if self.multiworld.level_gate_costs[self.player].value == 0: + if self.options.level_gate_costs.value == 0: gate_cost_mult = 0.6 - elif self.multiworld.level_gate_costs[self.player].value == 1: + elif self.options.level_gate_costs.value == 1: gate_cost_mult = 0.8 shuffled_region_list = list(range(30)) @@ -253,8 +255,8 @@ class SA2BWorld(World): total_levels_added += 1 if levels_added_to_gate >= levels_per_gate[current_gate]: current_gate += 1 - if current_gate > self.multiworld.number_of_level_gates[self.player].value: - current_gate = self.multiworld.number_of_level_gates[self.player].value + if current_gate > self.options.number_of_level_gates.value: + current_gate = self.options.number_of_level_gates.value else: current_gate_emblems = max( math.floor(total_emblem_count * math.pow(total_levels_added / 30.0, 2.0) * gate_cost_mult), current_gate) @@ -266,38 +268,70 @@ 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) - 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) + connect_regions(self.multiworld, self, 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) itempool += [self.create_item(ItemName.emblem) for _ in range(max_required_emblems)] non_required_emblems = (total_emblem_count - max_required_emblems) - junk_count = math.floor(non_required_emblems * (self.multiworld.junk_fill_percentage[self.player].value / 100.0)) + junk_count = math.floor(non_required_emblems * (self.options.junk_fill_percentage.value / 100.0)) itempool += [self.create_item(ItemName.emblem, True) for _ in range(non_required_emblems - junk_count)] # Carve Traps out of junk_count trap_weights = [] - trap_weights += ([ItemName.omochao_trap] * self.multiworld.omochao_trap_weight[self.player].value) - trap_weights += ([ItemName.timestop_trap] * self.multiworld.timestop_trap_weight[self.player].value) - trap_weights += ([ItemName.confuse_trap] * self.multiworld.confusion_trap_weight[self.player].value) - trap_weights += ([ItemName.tiny_trap] * self.multiworld.tiny_trap_weight[self.player].value) - trap_weights += ([ItemName.gravity_trap] * self.multiworld.gravity_trap_weight[self.player].value) - trap_weights += ([ItemName.exposition_trap] * self.multiworld.exposition_trap_weight[self.player].value) - #trap_weights += ([ItemName.darkness_trap] * self.multiworld.darkness_trap_weight[self.player].value) - 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.omochao_trap] * self.options.omochao_trap_weight.value) + trap_weights += ([ItemName.timestop_trap] * self.options.timestop_trap_weight.value) + trap_weights += ([ItemName.confuse_trap] * self.options.confusion_trap_weight.value) + trap_weights += ([ItemName.tiny_trap] * self.options.tiny_trap_weight.value) + trap_weights += ([ItemName.gravity_trap] * self.options.gravity_trap_weight.value) + trap_weights += ([ItemName.exposition_trap] * self.options.exposition_trap_weight.value) + #trap_weights += ([ItemName.darkness_trap] * self.options.darkness_trap_weight.value) + trap_weights += ([ItemName.ice_trap] * self.options.ice_trap_weight.value) + trap_weights += ([ItemName.slow_trap] * self.options.slow_trap_weight.value) + trap_weights += ([ItemName.cutscene_trap] * self.options.cutscene_trap_weight.value) + trap_weights += ([ItemName.reverse_trap] * self.options.reverse_trap_weight.value) + trap_weights += ([ItemName.pong_trap] * self.options.pong_trap_weight.value) junk_count += extra_junk_count - trap_count = 0 if (len(trap_weights) == 0) else math.ceil(junk_count * (self.multiworld.trap_fill_percentage[self.player].value / 100.0)) + trap_count = 0 if (len(trap_weights) == 0) else math.ceil(junk_count * (self.options.trap_fill_percentage.value / 100.0)) junk_count -= trap_count + chao_active = self.any_chao_locations_active() junk_pool = [] junk_keys = list(junk_table.keys()) + + # Chao Junk + if chao_active: + junk_keys += list(chaos_drives_table.keys()) + eggs_keys = list(eggs_table.keys()) + fruits_keys = list(fruits_table.keys()) + seeds_keys = list(seeds_table.keys()) + hats_keys = list(hats_table.keys()) + eggs_count = 0 + seeds_count = 0 + hats_count = 0 + for i in range(junk_count): - junk_item = self.multiworld.random.choice(junk_keys) - junk_pool.append(self.create_item(junk_item)) + junk_type = self.random.randint(0, len(junk_keys) + 3) + + if chao_active and junk_type == len(junk_keys) + 0 and eggs_count < 20: + junk_item = self.multiworld.random.choice(eggs_keys) + junk_pool.append(self.create_item(junk_item)) + eggs_count += 1 + elif chao_active and junk_type == len(junk_keys) + 1: + junk_item = self.multiworld.random.choice(fruits_keys) + junk_pool.append(self.create_item(junk_item)) + elif chao_active and junk_type == len(junk_keys) + 2 and seeds_count < 12: + junk_item = self.multiworld.random.choice(seeds_keys) + junk_pool.append(self.create_item(junk_item)) + seeds_count += 1 + elif chao_active and junk_type == len(junk_keys) + 3 and hats_count < 20: + junk_item = self.multiworld.random.choice(hats_keys) + junk_pool.append(self.create_item(junk_item)) + hats_count += 1 + else: + junk_item = self.multiworld.random.choice(junk_keys) + junk_pool.append(self.create_item(junk_item)) itempool += junk_pool @@ -310,95 +344,6 @@ class SA2BWorld(World): self.multiworld.itempool += itempool - # Music Shuffle - if self.multiworld.music_shuffle[self.player] == "levels": - musiclist_o = list(range(0, 47)) - musiclist_s = musiclist_o.copy() - self.multiworld.random.shuffle(musiclist_s) - musiclist_o.extend(range(47, 78)) - musiclist_s.extend(range(47, 78)) - - if self.multiworld.sadx_music[self.player].value == 1: - musiclist_s = [x+100 for x in musiclist_s] - elif self.multiworld.sadx_music[self.player].value == 2: - for i in range(len(musiclist_s)): - if self.multiworld.random.randint(0,1): - musiclist_s[i] += 100 - - self.music_map = dict(zip(musiclist_o, musiclist_s)) - elif self.multiworld.music_shuffle[self.player] == "full": - musiclist_o = list(range(0, 78)) - musiclist_s = musiclist_o.copy() - self.multiworld.random.shuffle(musiclist_s) - - if self.multiworld.sadx_music[self.player].value == 1: - musiclist_s = [x+100 for x in musiclist_s] - elif self.multiworld.sadx_music[self.player].value == 2: - for i in range(len(musiclist_s)): - if self.multiworld.random.randint(0,1): - musiclist_s[i] += 100 - - self.music_map = dict(zip(musiclist_o, musiclist_s)) - elif self.multiworld.music_shuffle[self.player] == "singularity": - musiclist_o = list(range(0, 78)) - musiclist_s = [self.multiworld.random.choice(musiclist_o)] * len(musiclist_o) - - if self.multiworld.sadx_music[self.player].value == 1: - musiclist_s = [x+100 for x in musiclist_s] - elif self.multiworld.sadx_music[self.player].value == 2: - if self.multiworld.random.randint(0,1): - musiclist_s = [x+100 for x in musiclist_s] - - self.music_map = dict(zip(musiclist_o, musiclist_s)) - else: - musiclist_o = list(range(0, 78)) - musiclist_s = musiclist_o.copy() - - if self.multiworld.sadx_music[self.player].value == 1: - musiclist_s = [x+100 for x in musiclist_s] - elif self.multiworld.sadx_music[self.player].value == 2: - for i in range(len(musiclist_s)): - if self.multiworld.random.randint(0,1): - musiclist_s[i] += 100 - - self.music_map = dict(zip(musiclist_o, musiclist_s)) - - # 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: @@ -422,26 +367,32 @@ class SA2BWorld(World): return created_item def get_filler_item_name(self) -> str: - return self.multiworld.random.choice(list(junk_table.keys())) + junk_keys = list(junk_table.keys()) + + # Chao Junk + if self.any_chao_locations_active(): + junk_keys += list(chaos_drives_table.keys()) + + return self.multiworld.random.choice(junk_keys) def set_rules(self): - set_rules(self.multiworld, self.player, self.gate_bosses, self.boss_rush_map, self.mission_map, self.mission_count_map) + set_rules(self.multiworld, self, self.player, self.gate_bosses, self.boss_rush_map, self.mission_map, self.mission_count_map, self.black_market_costs) def write_spoiler(self, spoiler_handle: typing.TextIO): - if self.multiworld.number_of_level_gates[self.player].value > 0 or self.multiworld.goal[self.player].value in [4, 5, 6]: + if self.options.number_of_level_gates.value > 0 or self.options.goal.value in [4, 5, 6]: spoiler_handle.write("\n") header_text = "Sonic Adventure 2 Bosses for {}:\n" header_text = header_text.format(self.multiworld.player_name[self.player]) spoiler_handle.write(header_text) - if self.multiworld.number_of_level_gates[self.player].value > 0: + if self.options.number_of_level_gates.value > 0: for x in range(len(self.gate_bosses.values())): 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]: + if self.options.goal.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])) @@ -459,12 +410,21 @@ class SA2BWorld(World): ] no_hint_region_names = [ LocationName.cannon_core_region, - LocationName.chao_garden_beginner_region, - LocationName.chao_garden_intermediate_region, - LocationName.chao_garden_expert_region, + LocationName.chao_race_beginner_region, + LocationName.chao_race_intermediate_region, + LocationName.chao_race_expert_region, + LocationName.chao_karate_beginner_region, + LocationName.chao_karate_intermediate_region, + LocationName.chao_karate_expert_region, + LocationName.chao_karate_super_region, + LocationName.kart_race_beginner_region, + LocationName.kart_race_standard_region, + LocationName.kart_race_expert_region, + LocationName.chao_kindergarten_region, + LocationName.black_market_region, ] er_hint_data = {} - for i in range(self.multiworld.number_of_level_gates[self.player].value + 1): + for i in range(self.options.number_of_level_gates.value + 1): gate_name = gate_names[i] gate_region = self.multiworld.get_region(gate_name, self.player) if not gate_region: @@ -476,10 +436,353 @@ class SA2BWorld(World): for location in level_region.locations: er_hint_data[location.address] = gate_name + for i in range(self.options.black_market_slots.value): + location = self.multiworld.get_location(LocationName.chao_black_market_base + str(i + 1), self.player) + er_hint_data[location.address] = str(self.black_market_costs[i]) + " " + str(ItemName.market_token) + + hint_data[self.player] = er_hint_data @classmethod - def stage_fill_hook(cls, world, progitempool, usefulitempool, filleritempool, fill_locations): - if world.get_game_players("Sonic Adventure 2 Battle"): + def stage_fill_hook(cls, multiworld: MultiWorld, progitempool, usefulitempool, filleritempool, fill_locations): + if multiworld.get_game_players("Sonic Adventure 2 Battle"): progitempool.sort( key=lambda item: 0 if (item.name != 'Emblem') else 1) + + def get_levels_per_gate(self) -> list: + levels_per_gate = list() + max_gate_index = self.options.number_of_level_gates + average_level_count = 30 / (max_gate_index + 1) + levels_added = 0 + + for i in range(max_gate_index + 1): + levels_per_gate.append(average_level_count) + levels_added += average_level_count + additional_count_iterator = 0 + while levels_added < 30: + levels_per_gate[additional_count_iterator] += 1 + levels_added += 1 + additional_count_iterator += 1 if additional_count_iterator < max_gate_index else -max_gate_index + + if self.options.level_gate_distribution == 0 or self.options.level_gate_distribution == 2: + early_distribution = self.options.level_gate_distribution == 0 + levels_to_distribute = 5 + gate_index_offset = 0 + while levels_to_distribute > 0: + if levels_per_gate[0 + gate_index_offset] == 1 or \ + levels_per_gate[max_gate_index - gate_index_offset] == 1: + break + if early_distribution: + levels_per_gate[0 + gate_index_offset] += 1 + levels_per_gate[max_gate_index - gate_index_offset] -= 1 + else: + levels_per_gate[0 + gate_index_offset] -= 1 + levels_per_gate[max_gate_index - gate_index_offset] += 1 + gate_index_offset += 1 + if gate_index_offset > math.floor(max_gate_index / 2): + gate_index_offset = 0 + levels_to_distribute -= 1 + + return levels_per_gate + + def any_chao_locations_active(self) -> bool: + if self.options.chao_race_difficulty.value > 0 or \ + self.options.chao_karate_difficulty.value > 0 or \ + self.options.chao_stats.value > 0 or \ + self.options.chao_animal_parts or \ + self.options.chao_kindergarten or \ + self.options.black_market_slots.value > 0: + return True; + + return False + + def generate_music_data(self) -> typing.Dict[int, int]: + if self.options.music_shuffle == "levels": + musiclist_o = list(range(0, 47)) + musiclist_s = musiclist_o.copy() + self.random.shuffle(musiclist_s) + musiclist_o.extend(range(47, 78)) + musiclist_s.extend(range(47, 78)) + + if self.options.sadx_music.value == 1: + musiclist_s = [x+100 for x in musiclist_s] + elif self.options.sadx_music.value == 2: + for i in range(len(musiclist_s)): + if self.random.randint(0,1): + musiclist_s[i] += 100 + + return dict(zip(musiclist_o, musiclist_s)) + elif self.options.music_shuffle == "full": + musiclist_o = list(range(0, 78)) + musiclist_s = musiclist_o.copy() + self.random.shuffle(musiclist_s) + + if self.options.sadx_music.value == 1: + musiclist_s = [x+100 for x in musiclist_s] + elif self.options.sadx_music.value == 2: + for i in range(len(musiclist_s)): + if self.random.randint(0,1): + musiclist_s[i] += 100 + + return dict(zip(musiclist_o, musiclist_s)) + elif self.options.music_shuffle == "singularity": + musiclist_o = list(range(0, 78)) + musiclist_s = [self.random.choice(musiclist_o)] * len(musiclist_o) + + if self.options.sadx_music.value == 1: + musiclist_s = [x+100 for x in musiclist_s] + elif self.options.sadx_music.value == 2: + if self.random.randint(0,1): + musiclist_s = [x+100 for x in musiclist_s] + + return dict(zip(musiclist_o, musiclist_s)) + else: + musiclist_o = list(range(0, 78)) + musiclist_s = musiclist_o.copy() + + if self.options.sadx_music.value == 1: + musiclist_s = [x+100 for x in musiclist_s] + elif self.options.sadx_music.value == 2: + for i in range(len(musiclist_s)): + if self.random.randint(0,1): + musiclist_s[i] += 100 + + return dict(zip(musiclist_o, musiclist_s)) + + def generate_voice_data(self) -> typing.Dict[int, int]: + if self.options.voice_shuffle == "shuffled": + voicelist_o = list(range(0, 2623)) + voicelist_s = voicelist_o.copy() + self.random.shuffle(voicelist_s) + + return dict(zip(voicelist_o, voicelist_s)) + elif self.options.voice_shuffle == "rude": + voicelist_o = list(range(0, 2623)) + voicelist_s = voicelist_o.copy() + self.random.shuffle(voicelist_s) + + for i in range(len(voicelist_s)): + if self.random.randint(1,100) > 80: + voicelist_s[i] = 17 + + return dict(zip(voicelist_o, voicelist_s)) + elif self.options.voice_shuffle == "chao": + voicelist_o = list(range(0, 2623)) + voicelist_s = voicelist_o.copy() + self.random.shuffle(voicelist_s) + + for i in range(len(voicelist_s)): + voicelist_s[i] = self.random.choice(range(2586, 2608)) + + return dict(zip(voicelist_o, voicelist_s)) + elif self.options.voice_shuffle == "singularity": + voicelist_o = list(range(0, 2623)) + voicelist_s = [self.random.choice(voicelist_o)] * len(voicelist_o) + + return dict(zip(voicelist_o, voicelist_s)) + else: + voicelist_o = list(range(0, 2623)) + voicelist_s = voicelist_o.copy() + + return dict(zip(voicelist_o, voicelist_s)) + + def generate_chao_egg_data(self) -> typing.Dict[int, int]: + if self.options.shuffle_starting_chao_eggs: + egglist_o = list(range(0, 4)) + egglist_s = self.random.sample(range(0,54), 4) + + return dict(zip(egglist_o, egglist_s)) + else: + # Indicate these are not shuffled + egglist_o = [0, 1, 2, 3] + egglist_s = [255, 255, 255, 255] + + return dict(zip(egglist_o, egglist_s)) + + def generate_chao_name_data(self) -> typing.Dict[int, int]: + number_of_names = 30 + name_list_o = list(range(number_of_names * 7)) + name_list_s = [] + + name_list_base = [] + name_list_copy = list(self.multiworld.player_name.values()) + name_list_copy.remove(self.multiworld.player_name[self.player]) + + if len(name_list_copy) >= number_of_names: + name_list_base = self.random.sample(name_list_copy, number_of_names) + else: + name_list_base = name_list_copy + self.random.shuffle(name_list_base) + + name_list_base += self.random.sample(sample_chao_names, number_of_names - len(name_list_base)) + + for name in name_list_base: + for char_idx in range(7): + if char_idx < len(name): + name_list_s.append(chao_name_conversion[name[char_idx]]) + else: + name_list_s.append(0x00) + + return dict(zip(name_list_o, name_list_s)) + + def generate_black_market_data(self) -> typing.Dict[int, int]: + if self.options.black_market_slots.value == 0: + return {} + + ring_costs = [50, 75, 100] + + market_data = {} + item_names = [] + player_names = [] + progression_flags = [] + totally_real_item_names_copy = totally_real_item_names.copy() + location_names = [(LocationName.chao_black_market_base + str(i)) for i in range(1, self.options.black_market_slots.value + 1)] + locations = [self.multiworld.get_location(location_name, self.player) for location_name in location_names] + for location in locations: + if location.item.classification & ItemClassification.trap: + item_name = self.random.choice(totally_real_item_names_copy) + totally_real_item_names_copy.remove(item_name) + item_names.append(item_name) + else: + item_names.append(location.item.name) + player_names.append(self.multiworld.player_name[location.item.player]) + + if location.item.classification & ItemClassification.progression or location.item.classification & ItemClassification.trap: + progression_flags.append(2) + elif location.item.classification & ItemClassification.useful: + progression_flags.append(1) + else: + progression_flags.append(0) + + for item_idx in range(self.options.black_market_slots.value): + for chr_idx in range(len(item_names[item_idx][:26])): + market_data[(item_idx * 46) + chr_idx] = ord(item_names[item_idx][chr_idx]) + for chr_idx in range(len(player_names[item_idx][:16])): + market_data[(item_idx * 46) + 26 + chr_idx] = ord(player_names[item_idx][chr_idx]) + + market_data[(item_idx * 46) + 42] = ring_costs[progression_flags[item_idx]] * self.options.black_market_price_multiplier.value + + return market_data + + def generate_er_layout(self) -> typing.Dict[int, int]: + if not self.options.chao_entrance_randomization: + return {} + + er_layout = {} + + start_exit = self.random.randint(0, 3) + accessible_rooms = [] + + multi_rooms_copy = multi_rooms.copy() + single_rooms_copy = single_rooms.copy() + all_exits_copy = all_exits.copy() + all_destinations_copy = all_destinations.copy() + + multi_rooms_copy.remove(0x07) + accessible_rooms.append(0x07) + + # Place Kindergarten somewhere sane + exit_choice = self.random.choice(valid_kindergarten_exits) + exit_room = exit_to_room_map[exit_choice] + all_exits_copy.remove(exit_choice) + multi_rooms_copy.remove(exit_room) + + destination = 0x06 + single_rooms_copy.remove(destination) + all_destinations_copy.remove(destination) + + er_layout[exit_choice] = destination + + reverse_exit = self.random.choice(room_to_exits_map[destination]) + + er_layout[reverse_exit] = exit_to_room_map[exit_choice] + + all_exits_copy.remove(reverse_exit) + all_destinations_copy.remove(exit_room) + + # Connect multi-exit rooms + loop_guard = 0 + while len(multi_rooms_copy) > 0: + loop_guard += 1 + if loop_guard > 2000: + logging.warning(f"Failed to generate Chao Entrance Randomization for player: {self.multiworld.player_name[self.player]}") + return {} + + exit_room = self.random.choice(accessible_rooms) + possible_exits = [exit for exit in room_to_exits_map[exit_room] if exit in all_exits_copy] + if len(possible_exits) == 0: + continue + exit_choice = self.random.choice(possible_exits) + all_exits_copy.remove(exit_choice) + + destination = self.random.choice(multi_rooms_copy) + multi_rooms_copy.remove(destination) + all_destinations_copy.remove(destination) + accessible_rooms.append(destination) + + er_layout[exit_choice] = destination + + reverse_exit = self.random.choice(room_to_exits_map[destination]) + + er_layout[reverse_exit] = exit_room + + all_exits_copy.remove(reverse_exit) + all_destinations_copy.remove(exit_room) + + # Connect dead-end rooms + loop_guard = 0 + while len(single_rooms_copy) > 0: + loop_guard += 1 + if loop_guard > 2000: + logging.warning(f"Failed to generate Chao Entrance Randomization for player: {self.multiworld.player_name[self.player]}") + return {} + + exit_room = self.random.choice(accessible_rooms) + possible_exits = [exit for exit in room_to_exits_map[exit_room] if exit in all_exits_copy] + if len(possible_exits) == 0: + continue + exit_choice = self.random.choice(possible_exits) + all_exits_copy.remove(exit_choice) + + destination = self.random.choice(single_rooms_copy) + single_rooms_copy.remove(destination) + all_destinations_copy.remove(destination) + + er_layout[exit_choice] = destination + + reverse_exit = self.random.choice(room_to_exits_map[destination]) + + er_layout[reverse_exit] = exit_room + + all_exits_copy.remove(reverse_exit) + all_destinations_copy.remove(exit_room) + + # Connect remaining exits + loop_guard = 0 + while len(all_exits_copy) > 0: + loop_guard += 1 + if loop_guard > 2000: + logging.warning(f"Failed to generate Chao Entrance Randomization for player: {self.multiworld.player_name[self.player]}") + return {} + + exit_room = self.random.choice(all_destinations_copy) + possible_exits = [exit for exit in room_to_exits_map[exit_room] if exit in all_exits_copy] + if len(possible_exits) == 0: + continue + exit_choice = self.random.choice(possible_exits) + all_exits_copy.remove(exit_choice) + all_destinations_copy.remove(exit_room) + + destination = self.random.choice(all_destinations_copy) + all_destinations_copy.remove(destination) + + er_layout[exit_choice] = destination + + possible_reverse_exits = [exit for exit in room_to_exits_map[destination] if exit in all_exits_copy] + reverse_exit = self.random.choice(possible_reverse_exits) + + er_layout[reverse_exit] = exit_room + + all_exits_copy.remove(reverse_exit) + + return er_layout diff --git a/worlds/sa2b/docs/setup_en.md b/worlds/sa2b/docs/setup_en.md index b30255ad..2ac00a3f 100644 --- a/worlds/sa2b/docs/setup_en.md +++ b/worlds/sa2b/docs/setup_en.md @@ -127,9 +127,6 @@ If you wish to use the `SADX Music` option of the Randomizer, you must own a cop - Mission 1 is missing a texture in the stage select UI. - Most likely another mod is conflicting and overwriting the texture pack. It is recommeded to have the SA2B Archipelago mod load last in the mod loader. -- Received Cutscene Traps don't play after beating a level. - - Make sure you don't have the "`Skip Intro`" option enabled in the mod manager. - ## Save File Safeguard (Advanced Option) The mod contains a save file safeguard which associates a savefile to a specific Archipelago seed. By default, save files can only connect to Archipelago servers that match their seed. The safeguard can be disabled in the mod config.ini by setting `IgnoreFileSafety` to true. This is NOT recommended for the standard user as it will allow any save file to connect and send items to the Archipelago server.