From 47ece209a279f06adc62ebf5fe9bd4e38bdce01a Mon Sep 17 00:00:00 2001 From: Pecomare Date: Sat, 22 Mar 2025 15:53:54 +0100 Subject: [PATCH 1/5] Add logic for 1st person mode glitch --- Logic.py | 12 + Rac2Options.py | 15 ++ Simplified Ratchet & Clank 2.yaml | 8 + data/Locations.py | 408 ++++++++++++++++++++++-------- 4 files changed, 336 insertions(+), 107 deletions(-) diff --git a/Logic.py b/Logic.py index 1b88745..ce5192d 100644 --- a/Logic.py +++ b/Logic.py @@ -71,3 +71,15 @@ def has_qwark_statuette(state: CollectionState, player: int) -> bool: def has_hypnomatic_parts(state: CollectionState, player: int) -> bool: return state.has(Items.HYPNOMATIC_PART.name, player, 3) + + +FIRST_PERSON_EASY = 1 +FIRST_PERSON_MEDIUM = 2 +FIRST_PERSON_HARD = 3 + + +def is_first_person_mode_glitch_location_allowed(state: CollectionState, player: int, difficulty: int) -> bool: + if state.multiworld.worlds[player].options.allow_first_person_mode: + return state.multiworld.worlds[player].options.allow_first_person_mode_glitch_locations >= difficulty + + return false diff --git a/Rac2Options.py b/Rac2Options.py index fa8cba8..6e58ccd 100644 --- a/Rac2Options.py +++ b/Rac2Options.py @@ -108,6 +108,20 @@ class ExtendWeaponProgression(Toggle): display_name = "Extended Weapon Progression" +class AllowFirstPersonModeGlitchLocations(Choice): + """Allows the logic to use checks reachable with 1st person mode glitch. + The setting relates to the difficulty of performing the glitch. For exmaple: + Easy: Getting the Platinum Bolt near the Tractor Beam exchange in Oozla. + Medium: Getting to the Notak Worker Bots without the Heli-pack nor the Thermanator. + Hard: Getting to the Mutated Protopet without the Hypnomatic.""" + display_name = "Allow 1st Person Mode Glitch" + option_no = 0 + option_easy = 1 + option_medium = 2 + option_hard = 3 + default = 0 + + @dataclass class Rac2Options(PerGameCommonOptions): start_inventory_from_pool: StartInventoryPool @@ -126,3 +140,4 @@ class Rac2Options(PerGameCommonOptions): weapon_xp_multiplier: WeaponExperienceMultiplier extra_spaceship_challenge_locations: ExtraSpaceshipChallengeLocations extend_weapon_progression: ExtendWeaponProgression + allow_first_person_mode_glitch_locations: AllowFirstPersonModeGlitchLocations diff --git a/Simplified Ratchet & Clank 2.yaml b/Simplified Ratchet & Clank 2.yaml index 991fa9a..74439f7 100644 --- a/Simplified Ratchet & Clank 2.yaml +++ b/Simplified Ratchet & Clank 2.yaml @@ -104,6 +104,14 @@ Ratchet & Clank 2: # This effectively makes all weapons that are usually restricted to NG+ available with enough grinding. extend_weapon_progression: false + # Allows the logic to use checks reachable with 1st person mode glitch + # Values are: no, easy, medium and hard + # The setting relates to the difficulty of performing the glitch. For exmaple: + # Easy: Getting the Platinum Bolt near the Tractor Beam exchange in Oozla. + # Medium: Getting to the Notak Worker Bots without the Heli-pack nor the Thermanator. + # Hard: Getting to the Mutated Protopet without the Hypnomatic. + allow_first_person_mode_glitch_locations: no + # Item & Location Options local_items: # Forces these items to be in their native world. diff --git a/data/Locations.py b/data/Locations.py index f541441..70617e0 100644 --- a/data/Locations.py +++ b/data/Locations.py @@ -16,18 +16,41 @@ class LocationData(NamedTuple): """ Oozla """ OOZLA_OUTSIDE_MEGACORP_STORE = LocationData(10, "Oozla: Outside Megacorp Store - Dynamo") -OOZLA_END_STORE_CUTSCENE = LocationData(11, "Oozla: End of Store Cutscene", can_dynamo) +OOZLA_END_STORE_CUTSCENE = LocationData( + 11, "Oozla: End of Store Cutscene", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or can_dynamo(state, player) +) OOZLA_MEGACORP_SCIENTIST = LocationData(12, "Oozla: Megacorp Scientist - Tractor Beam") -OOZLA_TRACTOR_PUZZLE_PB = LocationData(13, "Oozla: Tractor Puzzle - Platinum Bolt", can_tractor) -OOZLA_SWAMP_RUINS_PB = LocationData(14, "Oozla: Swamp Ruins - Platinum Bolt", can_dynamo) +OOZLA_TRACTOR_PUZZLE_PB = LocationData( + 13, "Oozla: Tractor Puzzle - Platinum Bolt", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_tractor(state, player) +) +OOZLA_SWAMP_RUINS_PB = LocationData( + 14, "Oozla: Swamp Ruins - Platinum Bolt", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or can_dynamo(state, player) +) OOZLA_SWAMP_MONSTER_II = LocationData( 15, "Oozla: Swamp Monster II - Box Breaker", - lambda state, player: can_dynamo(state, player) and can_gravity(state, player) + lambda state, player: + can_dynamo(state, player) + and can_gravity(state, player) ) """ Maktar """ MAKTAR_ARENA_CHALLENGE = LocationData(20, "Maktar: Arena Challenge - Electrolyzer") -MAKTAR_PHOTO_BOOTH = LocationData(21, "Maktar: Photo Booth", can_electrolyze) +MAKTAR_PHOTO_BOOTH = LocationData( + 21, "Maktar: Photo Booth", + lambda state, player: + (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + and can_improved_jump(state, player)) + or can_electrolyze(state, player) +) MAKTAR_DEACTIVATE_JAMMING_ARRAY = LocationData(22, "Maktar: Deactivate Jamming Array", can_tractor) MAKTAR_JAMMING_ARRAY_PB = LocationData(23, "Maktar: Jamming Array - Platinum Bolt", can_tractor) MAKTAR_CRANE_PB = LocationData(24, "Maktar: Crane - Platinum Bolt") @@ -37,22 +60,35 @@ class LocationData(NamedTuple): ENDAKO_CLANK_APARTMENT_GB = LocationData(31, "Endako: Clank's Apartment - Grindboots") ENDAKO_RESCUE_CLANK_HELI = LocationData(32, "Endako: Rescue Clank Heli-Pack", can_electrolyze) ENDAKO_RESCUE_CLANK_THRUSTER = LocationData(33, "Endako: Rescue Clank Thruster-Pack", can_electrolyze) -ENDAKO_LEDGE_PB = LocationData(34, "Endako: Ledge - Platinum Bolt", ) +ENDAKO_LEDGE_PB = LocationData(34, "Endako: Ledge - Platinum Bolt") ENDAKO_CRANE_PB = LocationData(35, "Endako: Crane - Platinum Bolt", can_electrolyze) ENDAKO_CRANE_NT = LocationData( 36, "Endako: Crane - Nanotech Boost", - lambda state, player: can_electrolyze(state, player) and can_infiltrate(state, player) + lambda state, player: + can_electrolyze(state, player) + and can_infiltrate(state, player) ) """ Barlow """ -BARLOW_INVENTOR = LocationData(40, "Barlow: Inventor - Thermanator", can_swingshot) +BARLOW_INVENTOR = LocationData( + 40, "Barlow: Inventor - Thermanator", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_swingshot(state, player) +) BARLOW_HOVERBIKE_RACE_TRANSMISSION = LocationData( 41, "Barlow: Hoverbike Race Transmission", - lambda state, player: can_improved_jump(state, player) and can_electrolyze(state, player) + lambda state, player: + can_electrolyze(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_improved_jump(state, player)) ) BARLOW_HOVERBIKE_RACE_PB = LocationData( 42, "Barlow: Hoverbike Race - Platinum Bolt", - lambda state, player: can_improved_jump(state, player) and can_electrolyze(state, player) + lambda state, player: + can_electrolyze(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_improved_jump(state, player)) ) BARLOW_HOUND_CAVE_PB = LocationData(43, "Barlow: Hound Cave - Platinum Bolt", can_swingshot) @@ -79,41 +115,86 @@ class LocationData(NamedTuple): """ Notak """ NOTAK_TOP_PIER_TELESCREEN = LocationData( 60, "Notak: Top of Pier Telescreen", - lambda state, player: can_improved_jump(state, player) and can_thermanate(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_improved_jump(state, player) + and can_thermanate(state, player)) ) NOTAK_WORKER_BOTS = LocationData( 61, "Notak: Worker Bots", - lambda state, player: can_heli(state, player) and can_thermanate(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_heli(state, player) + and can_thermanate(state, player)) ) NOTAK_BEHIND_BUILDING_PB = LocationData(62, "Notak: Behind Building - Platinum Bolt") NOTAK_PROMENADE_SIGN_PB = LocationData(63, "Notak: Promenade Sign - Platinum Bolt") NOTAK_TIMED_DYNAMO_PB = LocationData( 64, "Notak: Timed Dynamo - Platinum Bolt", lambda state, player: - can_improved_jump(state, player) - and can_thermanate(state, player) - and can_dynamo(state, player) + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_improved_jump(state, player) + and can_thermanate(state, player) + and can_dynamo(state, player)) ) NOTAK_PROMENADE_END_NT = LocationData(65, "Notak: Promenade End - Nanotech Boost") """ Siberius """ SIBERIUS_DEFEAT_THIEF = LocationData(70, "Siberius: Defeat Thief", can_swingshot) -SIBERIUS_FLAMEBOT_LEDGE_PB = LocationData(71, "Siberius: Flamebot Ledge - Platinum Bolt", can_tractor) -SIBERIUS_FENCED_AREA_PB = LocationData(72, "Siberius: Fenced Area - Platinum Bolt", can_heli) +SIBERIUS_FLAMEBOT_LEDGE_PB = LocationData( + 71, "Siberius: Flamebot Ledge - Platinum Bolt", + lambda state, player: + can_tractor(state, player) + or is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) +) +SIBERIUS_FENCED_AREA_PB = LocationData( + 72, "Siberius: Fenced Area - Platinum Bolt", + lambda state, player: + can_heli(state, player) + or is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) +) """ Tabora """ -# NOTICE: Heli-Pack and Swingshot are already logically required in order to access this planet -TABORA_MEET_ANGELA = LocationData(80, "Tabora: Meet Angela") -TABORA_UNDERGROUND_MINES_END = LocationData(81, "Tabora: Underground Mines - Glider", can_thermanate) -TABORA_UNDERGROUND_MINES_PB = LocationData(82, "Tabora: Underground Mines - Platinum Bolt", can_thermanate) +TABORA_MEET_ANGELA = LocationData( + 80, "Tabora: Meet Angela", + lambda state, player: + can_heli(state, player) + and can_swingshot(state, player) +) +TABORA_UNDERGROUND_MINES_END = LocationData( + 81, "Tabora: Underground Mines - Glider", + lambda state, player: + can_heli(state, player) + and can_swingshot(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_thermanate(state, player)) +) +TABORA_UNDERGROUND_MINES_PB = LocationData( + 82, "Tabora: Underground Mines - Platinum Bolt", + lambda state, player: + can_heli(state, player) + and can_swingshot(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_thermanate(state, player)) +) TABORA_CANYON_GLIDE_PB = LocationData( 83, "Tabora: Canyon Glide - Platinum Bolt", - lambda state, player: can_thermanate(state, player) and can_glide(state, player) + lambda state, player: + can_heli(state, player) + and can_swingshot(state, player) + and can_glide(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_thermanate(state, player)) ) TABORA_NORTHEAST_DESERT_PB = LocationData(84, "Tabora: Northeast Desert - Platinum Bolt") TABORA_CANYON_GLIDE_PILLAR_NT = LocationData( 85, "Tabora: Canyon Glide Pillar - Nanotech Boost", - lambda state, player: can_thermanate(state, player) and can_glide(state, player) + lambda state, player: + can_heli(state, player) + and can_swingshot(state, player) + and can_glide(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_thermanate(state, player)) ) TABORA_OMNIWRENCH_10000 = LocationData( 86, "Tabora: OmniWrench 10000", @@ -124,32 +205,43 @@ class LocationData(NamedTuple): DOBBO_DEFEAT_THUG_LEADER = LocationData( 90, "Dobbo: Defeat Thug Leader", lambda state, player: - can_improved_jump(state, player) - and can_dynamo(state, player) - and can_swingshot(state, player) + can_swingshot(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_improved_jump(state, player) + and can_dynamo(state, player))) ) DOBBO_FACILITY_TERMINAL = LocationData( 91, "Dobbo: Facility Terminal", lambda state, player: - can_dynamo(state, player) - and can_swingshot(state, player) - and can_glide(state, player) - and can_electrolyze(state, player) + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_dynamo(state, player) + and can_swingshot(state, player) + and can_glide(state, player) + and can_electrolyze(state, player)) ) DOBBO_SPIDERBOT_ROOM_PB = LocationData( 92, "Dobbo: Spiderbot Room - Platinum Bolt", lambda state, player: - can_dynamo(state, player) - and can_swingshot(state, player) - and can_spiderbot(state, player) + can_swingshot(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY)) + or (can_dynamo(state, player) + and can_spiderbot(state, player)) ) DOBBO_FACILITY_GLIDE_PB = LocationData( 93, "Dobbo: Facility Glide End - Platinum Bolt", - lambda state, player: can_dynamo(state, player) and can_swingshot(state, player) and can_glide(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_dynamo(state, player) + and can_swingshot(state, player) + and can_glide(state, player)) ) DOBBO_FACILITY_GLIDE_NT = LocationData( 94, "Dobbo: Facility Glide Beginning - Nanotech Boost", - lambda state, player: can_dynamo(state, player) and can_swingshot(state, player) and can_glide(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_dynamo(state, player) + and can_swingshot(state, player) + and can_glide(state, player)) ) """ Hrugis """ @@ -175,105 +267,177 @@ class LocationData(NamedTuple): JOBA_FIRST_HOVERBIKE_RACE = LocationData(110, "Joba: First Hoverbike Race - Charge Boots", can_swingshot) JOBA_SHADY_SALESMAN = LocationData( 111, "Joba: Shady Salesman - Levitator", - lambda state, player: can_dynamo(state, player) and can_improved_jump(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_dynamo(state, player) + and can_improved_jump(state, player)) ) JOBA_ARENA_BATTLE = LocationData( 112, "Joba: Arena Battle - Gravity Boots", lambda state, player: - can_dynamo(state, player) - and can_improved_jump(state, player) - and can_levitate(state, player) + can_levitate(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_dynamo(state, player) + and can_improved_jump(state, player))) ) JOBA_ARENA_CAGE_MATCH = LocationData( 113, "Joba: Arena Cage Match - Infiltrator", lambda state, player: - can_dynamo(state, player) - and can_improved_jump(state, player) - and can_levitate(state, player) + can_levitate(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_dynamo(state, player) + and can_improved_jump(state, player))) ) JOBA_HIDDEN_CLIFF_PB = LocationData( 114, "Joba: Hidden Cliff - Platinum Bolt", - lambda state, player: can_dynamo(state, player) and can_swingshot(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_dynamo(state, player) + and can_swingshot(state, player)) ) JOBA_LEVITATOR_TOWER_PB = LocationData( 115, "Joba: Levitator Tower - Platinum Bolt", lambda state, player: - can_dynamo(state, player) - and can_improved_jump(state, player) - and can_levitate(state, player) + can_levitate(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_dynamo(state, player) + and can_improved_jump(state, player))) ) JOBA_HOVERBIKE_RACE_SHORTCUT_NT = LocationData(116, "Joba: Hoverbike Race Shortcut - Nanotech Boost", can_swingshot) -JOBA_TIMED_DYNAMO_NT = LocationData(117, "Joba: Timed Dynamo Course - Nanotech Boost", can_dynamo) +JOBA_TIMED_DYNAMO_NT = LocationData( + 117, "Joba: Timed Dynamo Course - Nanotech Boost", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or can_dynamo +) """ Todano """ TODANO_SEARCH_ROCKET_SILO = LocationData( 120, "Todano: Search Rocket Silo", lambda state, player: - can_improved_jump(state, player) - and can_electrolyze(state, player) - and can_infiltrate(state, player) + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_improved_jump(state, player) + and can_electrolyze(state, player) + and can_infiltrate(state, player)) ) TODANO_STUART_ZURGO_TRADE = LocationData( 121, "Todano: Stuart Zurgo Trade - Armor Magnetizer", lambda state, player: - can_electrolyze(state, player) - and can_tractor(state, player) - and has_qwark_statuette(state, player) + has_qwark_statuette(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) + or (can_tractor(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_electrolyze(state, player)))) ) TODANO_FACILITY_INTERIOR = LocationData( 122, "Todano: Facility Interior - Sheepinator", - lambda state, player: can_electrolyze(state, player) and can_tractor(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) + or (can_tractor(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_electrolyze(state, player))) ) TODANO_NEAR_STUART_ZURGO_PB = LocationData( 123, "Todano: Near Stuart Zurgo - Platinum Bolt", - lambda state, player: can_electrolyze(state, player) and can_tractor(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) + or (can_tractor(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_electrolyze(state, player))) ) TODANO_END_TOUR_PB = LocationData(124, "Todano: End of Tour - Platinum Bolt") TODANO_SPIDERBOT_CONVEYOR_PB = LocationData( 125, "Todano: Spiderbot Conveyor - Platinum Bolt", lambda state, player: - can_electrolyze(state, player) - and can_tractor(state, player) - and can_improved_jump(state, player) + can_improved_jump(state, player) and can_spiderbot(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) + or (can_tractor(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_electrolyze(state, player)))) ) TODANO_ROCKET_SILO_NT = LocationData( 126, "Todano: Rocket Silo - Nanotech Boost", - lambda state, player: can_electrolyze(state, player) and can_infiltrate(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_electrolyze(state, player) + and can_infiltrate(state, player)) ) """ Boldan """ BOLDAN_FIND_FIZZWIDGET = LocationData( 130, "Boldan: Find Fizzwidget", lambda state, player: - can_levitate(state, player) - and can_gravity(state, player) - and can_swingshot(state, player) + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) + or (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + and can_improved_jump(state, player)) + or (can_gravity(state, player) + and can_swingshot(state, player)) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_levitate(state, player)) ) BOLDAN_SPIDERBOT_ALLEY_PB = LocationData( 131, "Boldan: Spiderbot Alley - Platinum Bolt", - lambda state, player: can_levitate(state, player) and can_spiderbot(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_levitate(state, player) + and can_spiderbot(state, player)) ) BOLDAN_FLOATING_PLATFORM_PB = LocationData( 132, "Boldan: Floating Platform - Platinum Bolt", - lambda state, player: can_levitate(state, player) and can_gravity(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_gravity(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_levitate(state, player))) ) BOLDAN_UPPER_DOME_PB = LocationData( 133, "Boldan: Upper Dome - Platinum Bolt", lambda state, player: - can_levitate(state, player) - and can_gravity(state, player) - and can_swingshot(state, player) + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) + or (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + and can_improved_jump(state, player)) + or (can_gravity(state, player) + and can_swingshot(state, player)) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_levitate(state, player)) +) +BOLDAN_FOUNTAIN_NT = LocationData( + 134, "Boldan: Fountain - Nanotech Boost", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_levitate(state, player) ) -BOLDAN_FOUNTAIN_NT = LocationData(134, "Boldan: Fountain - Nanotech Boost", can_levitate) """ Aranos Prison """ -# NOTICE: Gravity Boots, Levitator and Infiltrator are already logically required in order to access this planet -ARANOS_CONTROL_ROOM = LocationData(140, "Aranos: Control Room") -ARANOS_PLUMBER = LocationData(141, "Aranos: Plumber - Qwark Statuette") -ARANOS_UNDER_SHIP_PB = LocationData(142, "Aranos: Under Ship - Platinum Bolt", can_heli) +ARANOS_CONTROL_ROOM = LocationData( + 140, "Aranos: Control Room", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) + or (can_infiltrate(state, player) + and can_levitate(state, player) + and (can_gravity(state, player) + or is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM))) +) +ARANOS_PLUMBER = LocationData( + 141, "Aranos: Plumber - Qwark Statuette", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or (can_gravity(state, player) + and (can_levitate(state, player))) +) +ARANOS_UNDER_SHIP_PB = LocationData( + 142, "Aranos: Under Ship - Platinum Bolt", + lambda state, player: + (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or can_gravity(state, player)) + and can_heli(state, player) +) ARANOS_OMNIWRENCH_12000 = LocationData( 143, "Aranos: OmniWrench 12000", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) + or can_gravity(state, player), checked_flag_address=lambda ram: ram.aranos_wrench_cutscene_flag ) @@ -301,53 +465,71 @@ class LocationData(NamedTuple): 160, "Snivelak: Rescue Angela", lambda state, player: can_swingshot(state, player) - and can_grind(state, player) - and can_gravity(state, player) - and can_dynamo(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_grind(state, player) + and can_gravity(state, player) + and can_dynamo(state, player))) ) SNIVELAK_DYNAMO_PLATFORMS_PB = LocationData( 161, "Snivelak: Dynamo Platforms - Platinum Bolt", lambda state, player: can_swingshot(state, player) - and can_grind(state, player) - and can_gravity(state, player) - and can_dynamo(state, player) - and can_heli(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_grind(state, player) + and can_gravity(state, player) + and can_dynamo(state, player) + and can_heli(state, player))) ) SNIVELAK_SWINGSHOT_TOWER_NT = LocationData( 162, "Snivelak: Swingshot Tower - Nanotech Boost", - lambda state, player: can_swingshot(state, player) and can_heli(state, player) + lambda state, player: + can_swingshot(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_heli(state, player)) ) """ Smolg """ SMOLG_BALLOON_TRANSMISSION = LocationData( 170, "Smolg: Balloon Transmission", lambda state, player: - can_improved_jump(state, player) - and can_dynamo(state, player) - and can_electrolyze(state, player) + can_electrolyze(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + and can_improved_jump(state, player) + and can_dynamo(state, player)) ) SMOLG_DISTRIBUTION_FACILITY_END = LocationData( 171, "Smolg: Distribution Facility End - Hypnomatic Part", access_rule=lambda state, player: - can_improved_jump(state, player) - and can_dynamo(state, player) - and can_electrolyze(state, player) - and can_grind(state, player) - and can_infiltrate(state, player), + can_electrolyze(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_improved_jump(state, player) + and can_dynamo(state, player) + and can_grind(state, player) + and can_infiltrate(state, player))), checked_flag_address=lambda ram: ram.hypnomatic_part1 ) SMOLG_MUTANT_CRAB = LocationData( 172, "Smolg: Mutant Crab", - lambda state, player: can_swingshot(state, player) and can_levitate(state, player) + lambda state, player: + can_levitate(state, player) + and (can_swingshot(state, player) + or (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + and can_electrolyze(state, player))) ) SMOLG_FLOATING_PLATFORM_PB = LocationData( 173, "Smolg: Floating Platform - Platinum Bolt", - lambda state, player: can_swingshot(state, player) and can_levitate(state, player) + lambda state, player: + can_levitate(state, player) + and (can_swingshot(state, player) + or (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + and can_electrolyze(state, player))) ) SMOLG_WAREHOUSE_PB = LocationData( 174, "Smolg: Warehouse - Platinum Bolt", - lambda state, player: can_improved_jump(state, player) and can_dynamo(state, player) + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or (can_improved_jump(state, player) + and can_dynamo(state, player)) ) """ Damosel """ @@ -382,7 +564,12 @@ class LocationData(NamedTuple): ) """ Grelbin """ -GRELBIN_FIND_ANGELA = LocationData(190, "Grelbin: Find Angela", can_hypnotize) +GRELBIN_FIND_ANGELA = LocationData( + 190, "Grelbin: Find Angela", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_hypnotize +) GRELBIN_MYSTIC_MORE_MOONSTONES = LocationData( 191, "Grelbin: Mystic More Moonstones - Hypnomatic Part", access_rule=lambda state, player: can_glide(state, player) and can_infiltrate(state, player), @@ -405,25 +592,32 @@ class LocationData(NamedTuple): YEEDIL_DEFEAT_MUTATED_PROTOPET = LocationData( None, "Yeedil: Defeat Mutated Protopet", lambda state, player: - can_swingshot(state, player) - and can_hypnotize(state, player) - and can_improved_jump(state, player) - and can_dynamo(state, player) - and can_infiltrate(state, player) - and can_electrolyze(state, player) + can_infiltrate(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) + or (can_swingshot(state, player) + and can_hypnotize(state, player) + and can_dynamo(state, player) + and can_electrolyze(state, player) + and can_improved_jump(state, player))) +) +YEEDIL_BRIDGE_GRINDRAIL_PB = LocationData( + 200, "Yeedil: Bridge Grindrail - Platinum Bolt", + lambda state, player: + is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + or can_grind(state, player) ) -YEEDIL_BRIDGE_GRINDRAIL_PB = LocationData(200, "Yeedil: Bridge Grindrail - Platinum Bolt", can_grind) YEEDIL_TRACTOR_PILLAR_PB = LocationData( 201, "Yeedil: Tractor Pillar - Platinum Bolt", lambda state, player: - can_swingshot(state, player) - and can_hypnotize(state, player) - and can_improved_jump(state, player) - and can_dynamo(state, player) - and can_infiltrate(state, player) - and can_electrolyze(state, player) - and can_tractor(state, player) - and can_grind(state, player) + can_infiltrate(state, player) + and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) + or (can_swingshot(state, player) + and can_hypnotize(state, player) + and can_dynamo(state, player) + and can_electrolyze(state, player) + and can_improved_jump(state, player) + and can_tractor(state, player) + and can_grind(state, player))) ) """ Megacorp Vendor """ From 785eb459fdd5dfd6521dc7c53a77cfe7126e0e99 Mon Sep 17 00:00:00 2001 From: Pecomare Date: Sun, 23 Mar 2025 14:05:43 +0100 Subject: [PATCH 2/5] Modify structure of LocationData Replaced access_rule by vanilla_recommendation and alternative_routes, allowing easier addition of alternative routing --- Logic.py | 15 +- Regions.py | 15 +- __init__.py | 4 + data/Locations.py | 726 +++++++++++++++++++++++++--------------------- 4 files changed, 422 insertions(+), 338 deletions(-) diff --git a/Logic.py b/Logic.py index ce5192d..088d4cc 100644 --- a/Logic.py +++ b/Logic.py @@ -1,5 +1,13 @@ from BaseClasses import CollectionState +from typing import Callable, NamedTuple, Optional from .data import Items +from .Rac2Options import Rac2Options + + +class AlternativeRoute(NamedTuple): + condition: Callable[[Rac2Options], bool] + skipped_checks: list[Callable[[CollectionState, int], bool]] + alternative_checks: Optional[list[Callable[[CollectionState, int], bool]]] = None def can_dynamo(state: CollectionState, player: int) -> bool: @@ -76,10 +84,3 @@ def has_hypnomatic_parts(state: CollectionState, player: int) -> bool: FIRST_PERSON_EASY = 1 FIRST_PERSON_MEDIUM = 2 FIRST_PERSON_HARD = 3 - - -def is_first_person_mode_glitch_location_allowed(state: CollectionState, player: int, difficulty: int) -> bool: - if state.multiworld.worlds[player].options.allow_first_person_mode: - return state.multiworld.worlds[player].options.allow_first_person_mode_glitch_locations >= difficulty - - return false diff --git a/Regions.py b/Regions.py index 6e2dd1d..9eb1146 100644 --- a/Regions.py +++ b/Regions.py @@ -55,8 +55,19 @@ def planet_access_rule(state: CollectionState): def generate_access_rule(loc: LocationData) -> typing.Callable[[CollectionState], bool]: def access_rule(state: CollectionState): - if loc.access_rule: - return loc.access_rule(state, world.player) + if loc.vanilla_requirements: + requirements = loc.vanilla_requirements + if loc.alternative_routes: + for route in loc.alternative_routes: + if route.condition(state.multiworld.worlds[world.player].options): + requirements = [req for req in requirements if req not in route.skipped_checks] + if route.alternative_checks: + requirements.extend(route.alternative_checks) + for requirement in requirements: + if not requirement(state, world.player): + return False + return True + return True return access_rule diff --git a/__init__.py b/__init__.py index 6767ea2..d3ddad2 100644 --- a/__init__.py +++ b/__init__.py @@ -148,3 +148,7 @@ def get_options_as_dict(self) -> Dict[str, Any]: def fill_slot_data(self) -> Mapping[str, Any]: return self.get_options_as_dict() + + def generate_early(self): + if self.options.allow_first_person_mode_glitch_locations > 0: + assert self.options.allow_first_person_mode, "First Person Mode glitches enabled but not First Person Mode itself." \ No newline at end of file diff --git a/data/Locations.py b/data/Locations.py index 70617e0..07f461d 100644 --- a/data/Locations.py +++ b/data/Locations.py @@ -8,7 +8,8 @@ class LocationData(NamedTuple): location_id: Optional[int] name: str - access_rule: Optional[Callable[[CollectionState, int], bool]] = None + vanilla_requirements: Optional[list[Callable[[CollectionState, int], bool]]] = None + alternative_routes: Optional[list[AlternativeRoute]] = None checked_flag_address: Optional[Callable[["Addresses"], int]] = None enable_if: Optional[Callable[[Dict[str, Any]], bool]] = None is_vendor: bool = False @@ -18,79 +19,91 @@ class LocationData(NamedTuple): OOZLA_OUTSIDE_MEGACORP_STORE = LocationData(10, "Oozla: Outside Megacorp Store - Dynamo") OOZLA_END_STORE_CUTSCENE = LocationData( 11, "Oozla: End of Store Cutscene", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or can_dynamo(state, player) + vanilla_requirements=[can_dynamo], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo] + ) + ] ) OOZLA_MEGACORP_SCIENTIST = LocationData(12, "Oozla: Megacorp Scientist - Tractor Beam") OOZLA_TRACTOR_PUZZLE_PB = LocationData( 13, "Oozla: Tractor Puzzle - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_tractor(state, player) + vanilla_requirements=[can_tractor], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_tractor] + ) + ] ) OOZLA_SWAMP_RUINS_PB = LocationData( - 14, "Oozla: Swamp Ruins - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or can_dynamo(state, player) + 14, "Oozla: Swamp Ruins - Platinum Bolt", + vanilla_requirements=[can_dynamo], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo] + ) + ] ) OOZLA_SWAMP_MONSTER_II = LocationData( 15, "Oozla: Swamp Monster II - Box Breaker", - lambda state, player: - can_dynamo(state, player) - and can_gravity(state, player) + vanilla_requirements=[can_dynamo, can_gravity] ) """ Maktar """ MAKTAR_ARENA_CHALLENGE = LocationData(20, "Maktar: Arena Challenge - Electrolyzer") MAKTAR_PHOTO_BOOTH = LocationData( 21, "Maktar: Photo Booth", - lambda state, player: - (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - and can_improved_jump(state, player)) - or can_electrolyze(state, player) -) -MAKTAR_DEACTIVATE_JAMMING_ARRAY = LocationData(22, "Maktar: Deactivate Jamming Array", can_tractor) -MAKTAR_JAMMING_ARRAY_PB = LocationData(23, "Maktar: Jamming Array - Platinum Bolt", can_tractor) + vanilla_requirements=[can_electrolyze], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_electrolyze], + alternative_checks=[can_heli] + ) + ] +) +MAKTAR_DEACTIVATE_JAMMING_ARRAY = LocationData(22, "Maktar: Deactivate Jamming Array", [can_tractor]) +MAKTAR_JAMMING_ARRAY_PB = LocationData(23, "Maktar: Jamming Array - Platinum Bolt", [can_tractor]) MAKTAR_CRANE_PB = LocationData(24, "Maktar: Crane - Platinum Bolt") """ Endako """ ENDAKO_CLANK_APARTMENT_SS = LocationData(30, "Endako: Clank's Apartment - Swingshot") ENDAKO_CLANK_APARTMENT_GB = LocationData(31, "Endako: Clank's Apartment - Grindboots") -ENDAKO_RESCUE_CLANK_HELI = LocationData(32, "Endako: Rescue Clank Heli-Pack", can_electrolyze) -ENDAKO_RESCUE_CLANK_THRUSTER = LocationData(33, "Endako: Rescue Clank Thruster-Pack", can_electrolyze) +ENDAKO_RESCUE_CLANK_HELI = LocationData(32, "Endako: Rescue Clank Heli-Pack", [can_electrolyze]) +ENDAKO_RESCUE_CLANK_THRUSTER = LocationData(33, "Endako: Rescue Clank Thruster-Pack", [can_electrolyze]) ENDAKO_LEDGE_PB = LocationData(34, "Endako: Ledge - Platinum Bolt") -ENDAKO_CRANE_PB = LocationData(35, "Endako: Crane - Platinum Bolt", can_electrolyze) -ENDAKO_CRANE_NT = LocationData( - 36, "Endako: Crane - Nanotech Boost", - lambda state, player: - can_electrolyze(state, player) - and can_infiltrate(state, player) -) +ENDAKO_CRANE_PB = LocationData(35, "Endako: Crane - Platinum Bolt", [can_electrolyze]) +ENDAKO_CRANE_NT = LocationData(36, "Endako: Crane - Nanotech Boost", [can_electrolyze, can_infiltrate]) """ Barlow """ BARLOW_INVENTOR = LocationData( 40, "Barlow: Inventor - Thermanator", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_swingshot(state, player) + vanilla_requirements=[can_swingshot], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_swingshot] + ) + ] ) BARLOW_HOVERBIKE_RACE_TRANSMISSION = LocationData( 41, "Barlow: Hoverbike Race Transmission", - lambda state, player: - can_electrolyze(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_improved_jump(state, player)) + vanilla_requirements=[can_electrolyze, can_improved_jump], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_improved_jump] + ) + ] ) BARLOW_HOVERBIKE_RACE_PB = LocationData( 42, "Barlow: Hoverbike Race - Platinum Bolt", - lambda state, player: - can_electrolyze(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_improved_jump(state, player)) -) -BARLOW_HOUND_CAVE_PB = LocationData(43, "Barlow: Hound Cave - Platinum Bolt", can_swingshot) + vanilla_requirements=[can_electrolyze, can_improved_jump], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_improved_jump] + ) + ] +) +BARLOW_HOUND_CAVE_PB = LocationData(43, "Barlow: Hound Cave - Platinum Bolt", [can_swingshot]) """ Feltzin System """ FELTZIN_DEFEAT_THUG_SHIPS = LocationData(50, "Feltzin: Defeat Thug Ships") @@ -115,86 +128,94 @@ class LocationData(NamedTuple): """ Notak """ NOTAK_TOP_PIER_TELESCREEN = LocationData( 60, "Notak: Top of Pier Telescreen", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_improved_jump(state, player) - and can_thermanate(state, player)) + vanilla_requirements=[can_improved_jump, can_thermanate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_improved_jump, can_thermanate] + ) + ] ) NOTAK_WORKER_BOTS = LocationData( 61, "Notak: Worker Bots", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_heli(state, player) - and can_thermanate(state, player)) + vanilla_requirements=[can_heli, can_thermanate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_heli, can_thermanate] + ) + ] ) NOTAK_BEHIND_BUILDING_PB = LocationData(62, "Notak: Behind Building - Platinum Bolt") NOTAK_PROMENADE_SIGN_PB = LocationData(63, "Notak: Promenade Sign - Platinum Bolt") NOTAK_TIMED_DYNAMO_PB = LocationData( 64, "Notak: Timed Dynamo - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_improved_jump(state, player) - and can_thermanate(state, player) - and can_dynamo(state, player)) + vanilla_requirements=[can_improved_jump, can_thermanate, can_dynamo], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_improved_jump, can_thermanate, can_dynamo] + ) + ] ) NOTAK_PROMENADE_END_NT = LocationData(65, "Notak: Promenade End - Nanotech Boost") """ Siberius """ -SIBERIUS_DEFEAT_THIEF = LocationData(70, "Siberius: Defeat Thief", can_swingshot) +SIBERIUS_DEFEAT_THIEF = LocationData(70, "Siberius: Defeat Thief", [can_swingshot]) SIBERIUS_FLAMEBOT_LEDGE_PB = LocationData( 71, "Siberius: Flamebot Ledge - Platinum Bolt", - lambda state, player: - can_tractor(state, player) - or is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + vanilla_requirements=[can_tractor], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_tractor] + ) + ] ) SIBERIUS_FENCED_AREA_PB = LocationData( 72, "Siberius: Fenced Area - Platinum Bolt", - lambda state, player: - can_heli(state, player) - or is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) + vanilla_requirements=[can_heli], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_heli] + ) + ] ) """ Tabora """ -TABORA_MEET_ANGELA = LocationData( - 80, "Tabora: Meet Angela", - lambda state, player: - can_heli(state, player) - and can_swingshot(state, player) -) +TABORA_MEET_ANGELA = LocationData(80, "Tabora: Meet Angela", [can_heli, can_swingshot]) TABORA_UNDERGROUND_MINES_END = LocationData( 81, "Tabora: Underground Mines - Glider", - lambda state, player: - can_heli(state, player) - and can_swingshot(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_thermanate(state, player)) + vanilla_requirements=[can_heli, can_swingshot, can_thermanate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_thermanate] + ) + ] ) TABORA_UNDERGROUND_MINES_PB = LocationData( 82, "Tabora: Underground Mines - Platinum Bolt", - lambda state, player: - can_heli(state, player) - and can_swingshot(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_thermanate(state, player)) + vanilla_requirements=[can_heli, can_swingshot, can_thermanate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_thermanate] + ) + ] ) TABORA_CANYON_GLIDE_PB = LocationData( 83, "Tabora: Canyon Glide - Platinum Bolt", - lambda state, player: - can_heli(state, player) - and can_swingshot(state, player) - and can_glide(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_thermanate(state, player)) -) -TABORA_NORTHEAST_DESERT_PB = LocationData(84, "Tabora: Northeast Desert - Platinum Bolt") + vanilla_requirements=[can_heli, can_swingshot, can_thermanate, can_glide], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_thermanate] + ) + ] +) +TABORA_NORTHEAST_DESERT_PB = LocationData(84, "Tabora: Northeast Desert - Platinum Bolt", [can_heli, can_swingshot]) TABORA_CANYON_GLIDE_PILLAR_NT = LocationData( 85, "Tabora: Canyon Glide Pillar - Nanotech Boost", - lambda state, player: - can_heli(state, player) - and can_swingshot(state, player) - and can_glide(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_thermanate(state, player)) + vanilla_requirements=[can_heli, can_swingshot, can_thermanate, can_glide], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_thermanate] + ) + ] ) TABORA_OMNIWRENCH_10000 = LocationData( 86, "Tabora: OmniWrench 10000", @@ -204,44 +225,46 @@ class LocationData(NamedTuple): """ Dobbo """ DOBBO_DEFEAT_THUG_LEADER = LocationData( 90, "Dobbo: Defeat Thug Leader", - lambda state, player: - can_swingshot(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_improved_jump(state, player) - and can_dynamo(state, player))) + vanilla_requirements=[can_swingshot, can_improved_jump, can_dynamo], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_improved_jump, can_dynamo] + ) + ] ) DOBBO_FACILITY_TERMINAL = LocationData( 91, "Dobbo: Facility Terminal", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_dynamo(state, player) - and can_swingshot(state, player) - and can_glide(state, player) - and can_electrolyze(state, player)) + vanilla_requirements=[can_swingshot, can_glide, can_dynamo, can_electrolyze], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_swingshot, can_glide, can_dynamo, can_electrolyze] + ) + ] ) DOBBO_SPIDERBOT_ROOM_PB = LocationData( 92, "Dobbo: Spiderbot Room - Platinum Bolt", - lambda state, player: - can_swingshot(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY)) - or (can_dynamo(state, player) - and can_spiderbot(state, player)) + vanilla_requirements=[can_swingshot, can_dynamo, can_spiderbot], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_dynamo, can_spiderbot] + ) + ] ) DOBBO_FACILITY_GLIDE_PB = LocationData( 93, "Dobbo: Facility Glide End - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_dynamo(state, player) - and can_swingshot(state, player) - and can_glide(state, player)) + vanilla_requirements=[can_swingshot, can_dynamo, can_glide], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_swingshot, can_dynamo, can_glide]) + ] ) DOBBO_FACILITY_GLIDE_NT = LocationData( 94, "Dobbo: Facility Glide Beginning - Nanotech Boost", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_dynamo(state, player) - and can_swingshot(state, player) - and can_glide(state, player)) + vanilla_requirements=[can_swingshot, can_dynamo, can_glide], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_swingshot, can_dynamo, can_glide]) + ] ) """ Hrugis """ @@ -264,180 +287,235 @@ class LocationData(NamedTuple): ) """ Joba """ -JOBA_FIRST_HOVERBIKE_RACE = LocationData(110, "Joba: First Hoverbike Race - Charge Boots", can_swingshot) +JOBA_FIRST_HOVERBIKE_RACE = LocationData(110, "Joba: First Hoverbike Race - Charge Boots", [can_swingshot]) JOBA_SHADY_SALESMAN = LocationData( 111, "Joba: Shady Salesman - Levitator", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_dynamo(state, player) - and can_improved_jump(state, player)) + vanilla_requirements=[can_dynamo, can_improved_jump], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo, can_improved_jump] + ) + ] ) JOBA_ARENA_BATTLE = LocationData( 112, "Joba: Arena Battle - Gravity Boots", - lambda state, player: - can_levitate(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_dynamo(state, player) - and can_improved_jump(state, player))) + vanilla_requirements=[can_dynamo, can_improved_jump, can_levitate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo, can_improved_jump] + ) + ] ) JOBA_ARENA_CAGE_MATCH = LocationData( 113, "Joba: Arena Cage Match - Infiltrator", - lambda state, player: - can_levitate(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_dynamo(state, player) - and can_improved_jump(state, player))) + vanilla_requirements=[can_dynamo, can_improved_jump, can_levitate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo, can_improved_jump] + ) + ] ) JOBA_HIDDEN_CLIFF_PB = LocationData( 114, "Joba: Hidden Cliff - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_dynamo(state, player) - and can_swingshot(state, player)) + vanilla_requirements=[can_dynamo, can_improved_jump], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo, can_improved_jump] + ) + ] ) JOBA_LEVITATOR_TOWER_PB = LocationData( 115, "Joba: Levitator Tower - Platinum Bolt", - lambda state, player: - can_levitate(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_dynamo(state, player) - and can_improved_jump(state, player))) -) -JOBA_HOVERBIKE_RACE_SHORTCUT_NT = LocationData(116, "Joba: Hoverbike Race Shortcut - Nanotech Boost", can_swingshot) + vanilla_requirements=[can_dynamo, can_improved_jump, can_levitate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo, can_improved_jump] + ) + ] +) +JOBA_HOVERBIKE_RACE_SHORTCUT_NT = LocationData(116, "Joba: Hoverbike Race Shortcut - Nanotech Boost", [can_swingshot]) JOBA_TIMED_DYNAMO_NT = LocationData( 117, "Joba: Timed Dynamo Course - Nanotech Boost", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or can_dynamo + vanilla_requirements=[can_dynamo], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo] + ) + ] ) """ Todano """ TODANO_SEARCH_ROCKET_SILO = LocationData( 120, "Todano: Search Rocket Silo", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_improved_jump(state, player) - and can_electrolyze(state, player) - and can_infiltrate(state, player)) + vanilla_requirements=[can_electrolyze, can_improved_jump, can_infiltrate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_electrolyze, can_improved_jump, can_infiltrate] + ) + ] ) TODANO_STUART_ZURGO_TRADE = LocationData( 121, "Todano: Stuart Zurgo Trade - Armor Magnetizer", - lambda state, player: - has_qwark_statuette(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) - or (can_tractor(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_electrolyze(state, player)))) + vanilla_requirements=[can_tractor, can_electrolyze, has_qwark_statuette], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, + [can_tractor, can_electrolyze] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_electrolyze] + ) + ] ) TODANO_FACILITY_INTERIOR = LocationData( 122, "Todano: Facility Interior - Sheepinator", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) - or (can_tractor(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_electrolyze(state, player))) + vanilla_requirements=[can_tractor, can_electrolyze], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, + [can_tractor, can_electrolyze] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_electrolyze] + ) + ] ) TODANO_NEAR_STUART_ZURGO_PB = LocationData( 123, "Todano: Near Stuart Zurgo - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) - or (can_tractor(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_electrolyze(state, player))) + vanilla_requirements=[can_tractor, can_electrolyze], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, + [can_tractor, can_electrolyze] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_electrolyze] + ) + ] ) TODANO_END_TOUR_PB = LocationData(124, "Todano: End of Tour - Platinum Bolt") TODANO_SPIDERBOT_CONVEYOR_PB = LocationData( 125, "Todano: Spiderbot Conveyor - Platinum Bolt", - lambda state, player: - can_improved_jump(state, player) - and can_spiderbot(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) - or (can_tractor(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_electrolyze(state, player)))) + vanilla_requirements=[can_electrolyze, can_tractor, can_improved_jump, can_spiderbot], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, + [can_electrolyze, can_tractor] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_electrolyze] + ) + ] ) TODANO_ROCKET_SILO_NT = LocationData( 126, "Todano: Rocket Silo - Nanotech Boost", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_electrolyze(state, player) - and can_infiltrate(state, player)) + vanilla_requirements=[can_electrolyze, can_infiltrate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_electrolyze, can_infiltrate] + ) + ] ) """ Boldan """ BOLDAN_FIND_FIZZWIDGET = LocationData( 130, "Boldan: Find Fizzwidget", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) - or (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - and can_improved_jump(state, player)) - or (can_gravity(state, player) - and can_swingshot(state, player)) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_levitate(state, player)) + vanilla_requirements=[can_levitate, can_swingshot, can_gravity], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, + [can_levitate, can_swingshot, can_gravity] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_levitate, can_swingshot], + alternative_checks=[can_improved_jump] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_levitate] + ) + ] ) BOLDAN_SPIDERBOT_ALLEY_PB = LocationData( 131, "Boldan: Spiderbot Alley - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_levitate(state, player) - and can_spiderbot(state, player)) + vanilla_requirements=[can_levitate, can_spiderbot], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_levitate, can_spiderbot] + ) + ] ) BOLDAN_FLOATING_PLATFORM_PB = LocationData( 132, "Boldan: Floating Platform - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_gravity(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_levitate(state, player))) + vanilla_requirements=[can_levitate, can_gravity], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_levitate, can_gravity] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_levitate] + ) + ] ) BOLDAN_UPPER_DOME_PB = LocationData( 133, "Boldan: Upper Dome - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) - or (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - and can_improved_jump(state, player)) - or (can_gravity(state, player) - and can_swingshot(state, player)) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_levitate(state, player)) + vanilla_requirements=[can_levitate, can_swingshot, can_gravity], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, + [can_levitate, can_swingshot, can_gravity] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_levitate, can_swingshot], + alternative_checks=[can_improved_jump] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_levitate] + ) + ] ) BOLDAN_FOUNTAIN_NT = LocationData( 134, "Boldan: Fountain - Nanotech Boost", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_levitate(state, player) + vanilla_requirements=[can_levitate, can_spiderbot], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_levitate, can_spiderbot] + ) + ] ) """ Aranos Prison """ ARANOS_CONTROL_ROOM = LocationData( 140, "Aranos: Control Room", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) - or (can_infiltrate(state, player) - and can_levitate(state, player) - and (can_gravity(state, player) - or is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM))) + vanilla_requirements=[can_gravity, can_infiltrate, can_levitate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, + [can_gravity, can_infiltrate, can_levitate] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_gravity] + ) + ] ) ARANOS_PLUMBER = LocationData( 141, "Aranos: Plumber - Qwark Statuette", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or (can_gravity(state, player) - and (can_levitate(state, player))) + vanilla_requirements=[can_gravity, can_levitate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_gravity, can_levitate] + ) + ] ) ARANOS_UNDER_SHIP_PB = LocationData( 142, "Aranos: Under Ship - Platinum Bolt", - lambda state, player: - (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or can_gravity(state, player)) - and can_heli(state, player) + vanilla_requirements=[can_gravity, can_heli], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_gravity] + ) + ] ) ARANOS_OMNIWRENCH_12000 = LocationData( 143, "Aranos: OmniWrench 12000", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_MEDIUM) - or can_gravity(state, player), + vanilla_requirements=[can_gravity], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_gravity] + ) + ], checked_flag_address=lambda ram: ram.aranos_wrench_cutscene_flag ) @@ -463,161 +541,151 @@ class LocationData(NamedTuple): """ Snivelak """ SNIVELAK_RESCUE_ANGELA = LocationData( 160, "Snivelak: Rescue Angela", - lambda state, player: - can_swingshot(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_grind(state, player) - and can_gravity(state, player) - and can_dynamo(state, player))) + vanilla_requirements=[can_swingshot, can_grind, can_gravity, can_dynamo], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_grind, can_gravity, can_dynamo] + ) + ] ) SNIVELAK_DYNAMO_PLATFORMS_PB = LocationData( 161, "Snivelak: Dynamo Platforms - Platinum Bolt", - lambda state, player: - can_swingshot(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_grind(state, player) - and can_gravity(state, player) - and can_dynamo(state, player) - and can_heli(state, player))) + vanilla_requirements=[can_swingshot, can_grind, can_gravity, can_dynamo, can_heli], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_grind, can_gravity, can_dynamo, can_heli] + ) + ] ) SNIVELAK_SWINGSHOT_TOWER_NT = LocationData( 162, "Snivelak: Swingshot Tower - Nanotech Boost", - lambda state, player: - can_swingshot(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_heli(state, player)) + vanilla_requirements=[can_swingshot, can_heli], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_heli] + ) + ] ) """ Smolg """ SMOLG_BALLOON_TRANSMISSION = LocationData( 170, "Smolg: Balloon Transmission", - lambda state, player: - can_electrolyze(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - and can_improved_jump(state, player) - and can_dynamo(state, player)) + vanilla_requirements=[can_improved_jump, can_dynamo, can_electrolyze], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_improved_jump, can_dynamo] + ) + ] ) SMOLG_DISTRIBUTION_FACILITY_END = LocationData( 171, "Smolg: Distribution Facility End - Hypnomatic Part", - access_rule=lambda state, player: - can_electrolyze(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_improved_jump(state, player) - and can_dynamo(state, player) - and can_grind(state, player) - and can_infiltrate(state, player))), + vanilla_requirements=[can_improved_jump, can_dynamo, can_electrolyze, can_grind, can_infiltrate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_improved_jump, can_dynamo, can_grind, can_infiltrate] + ) + ], checked_flag_address=lambda ram: ram.hypnomatic_part1 ) SMOLG_MUTANT_CRAB = LocationData( 172, "Smolg: Mutant Crab", - lambda state, player: - can_levitate(state, player) - and (can_swingshot(state, player) - or (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - and can_electrolyze(state, player))) + vanilla_requirements=[can_swingshot, can_levitate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_swingshot], + alternative_checks=[can_electrolyze] + ) + ] ) SMOLG_FLOATING_PLATFORM_PB = LocationData( 173, "Smolg: Floating Platform - Platinum Bolt", - lambda state, player: - can_levitate(state, player) - and (can_swingshot(state, player) - or (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - and can_electrolyze(state, player))) + vanilla_requirements=[can_swingshot, can_levitate], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_swingshot], + alternative_checks=[can_electrolyze] + ) + ] ) SMOLG_WAREHOUSE_PB = LocationData( 174, "Smolg: Warehouse - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or (can_improved_jump(state, player) - and can_dynamo(state, player)) + vanilla_requirements=[can_dynamo, can_improved_jump], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_dynamo, can_improved_jump] + ) + ] ) """ Damosel """ -DAMOSEL_HYPNOTIST = LocationData( - 180, "Damosel: Hypnotist", - lambda state, player: - can_swingshot(state, player) - and can_improved_jump(state, player) - and can_thermanate(state, player) - and has_hypnomatic_parts(state, player) -) +DAMOSEL_HYPNOTIST = LocationData(180, "Damosel: Hypnotist", [can_swingshot, can_improved_jump, can_thermanate, has_hypnomatic_parts]) DAMOSEL_TRAIN_RAILS = LocationData( 181, "Damosel: Train Rails - Hypnomatic Part", - access_rule=can_grind, + vanilla_requirements=[can_grind], checked_flag_address=lambda ram: ram.hypnomatic_part2 ) DAMOSEL_DEFEAT_MOTHERSHIP = LocationData(182, "Damosel: Defeat Mothership - Mapper") -DAMOSEL_FROZEN_FOUNTAIN_PB = LocationData( - 183, "Damosel: Frozen Fountain - Platinum Bolt", - lambda state, player: - can_swingshot(state, player) - and can_improved_jump(state, player) - and can_thermanate(state, player) - and can_grind(state, player) -) -DAMOSEL_PYRAMID_PB = LocationData( - 184, "Damosel: Pyramid - Platinum Bolt", - lambda state, player: - can_swingshot(state, player) - and can_improved_jump(state, player) - and can_hypnotize(state, player) -) +DAMOSEL_FROZEN_FOUNTAIN_PB = LocationData(183, "Damosel: Frozen Fountain - Platinum Bolt", [can_swingshot, can_improved_jump, can_thermanate, can_grind]) +DAMOSEL_PYRAMID_PB = LocationData(184, "Damosel: Pyramid - Platinum Bolt", [can_swingshot, can_improved_jump, can_hypnotize]) """ Grelbin """ GRELBIN_FIND_ANGELA = LocationData( 190, "Grelbin: Find Angela", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_hypnotize + vanilla_requirements=[can_hypnotize], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_hypnotize] + ) + ] ) GRELBIN_MYSTIC_MORE_MOONSTONES = LocationData( 191, "Grelbin: Mystic More Moonstones - Hypnomatic Part", - access_rule=lambda state, player: can_glide(state, player) and can_infiltrate(state, player), + vanilla_requirements=[can_glide, can_infiltrate], checked_flag_address=lambda ram: ram.hypnomatic_part3 ) -GRELBIN_ICE_PLAINS_PB = LocationData( - 192, "Grelbin: Ice Plains - Platinum Bolt", - lambda state, player: can_glide(state, player) and can_infiltrate(state, player) -) -GRELBIN_UNDERWATER_TUNNEL_PB = LocationData(193, "Grelbin: Underwater Tunnel - Platinum Bolt", can_hypnotize) -GRELBIN_YETI_CAVE_PB = LocationData( - 194, "Grelbin: Yeti Cave - Platinum Bolt", - lambda state, player: - can_glide(state, player) - and can_infiltrate(state, player) - and can_hypnotize(state, player) -) +GRELBIN_ICE_PLAINS_PB = LocationData(192, "Grelbin: Ice Plains - Platinum Bolt", [can_glide, can_infiltrate]) +GRELBIN_UNDERWATER_TUNNEL_PB = LocationData(193, "Grelbin: Underwater Tunnel - Platinum Bolt", [can_hypnotize]) +GRELBIN_YETI_CAVE_PB = LocationData(194, "Grelbin: Yeti Cave - Platinum Bolt", [can_glide, can_infiltrate, can_hypnotize]) """ Yeedil """ YEEDIL_DEFEAT_MUTATED_PROTOPET = LocationData( None, "Yeedil: Defeat Mutated Protopet", - lambda state, player: - can_infiltrate(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) - or (can_swingshot(state, player) - and can_hypnotize(state, player) - and can_dynamo(state, player) - and can_electrolyze(state, player) - and can_improved_jump(state, player))) + vanilla_requirements=[can_hypnotize, can_swingshot, can_dynamo, can_infiltrate, can_electrolyze, can_improved_jump], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, + [can_hypnotize, can_swingshot, can_dynamo, can_electrolyze, can_improved_jump] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo, can_improved_jump] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_improved_jump] + ) + ] ) YEEDIL_BRIDGE_GRINDRAIL_PB = LocationData( 200, "Yeedil: Bridge Grindrail - Platinum Bolt", - lambda state, player: - is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_EASY) - or can_grind(state, player) + vanilla_requirements=[can_grind], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_grind] + ) + ] ) YEEDIL_TRACTOR_PILLAR_PB = LocationData( 201, "Yeedil: Tractor Pillar - Platinum Bolt", - lambda state, player: - can_infiltrate(state, player) - and (is_first_person_mode_glitch_location_allowed(state, player, FIRST_PERSON_HARD) - or (can_swingshot(state, player) - and can_hypnotize(state, player) - and can_dynamo(state, player) - and can_electrolyze(state, player) - and can_improved_jump(state, player) - and can_tractor(state, player) - and can_grind(state, player))) + vanilla_requirements=[can_hypnotize, can_swingshot, can_dynamo, can_infiltrate, can_electrolyze, can_improved_jump, can_tractor, can_grind], + alternative_routes=[ + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, + [can_hypnotize, can_swingshot, can_dynamo, can_electrolyze, can_improved_jump, can_tractor, can_grind] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, + [can_dynamo, can_improved_jump, can_tractor, can_grind] + ), + AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, + [can_improved_jump] + ) + ] ) """ Megacorp Vendor """ From 7204107e096b07951d45c3b2350a505a345c4a56 Mon Sep 17 00:00:00 2001 From: Pecomare Date: Tue, 25 Mar 2025 23:24:39 +0100 Subject: [PATCH 3/5] Move logic to Logic.py --- Logic.py | 705 +++++++++++++++++++++++++++++++++++++++++++++- Regions.py | 15 +- data/Locations.py | 635 +++++------------------------------------ 3 files changed, 776 insertions(+), 579 deletions(-) diff --git a/Logic.py b/Logic.py index 088d4cc..d43b937 100644 --- a/Logic.py +++ b/Logic.py @@ -1,15 +1,8 @@ from BaseClasses import CollectionState -from typing import Callable, NamedTuple, Optional from .data import Items from .Rac2Options import Rac2Options -class AlternativeRoute(NamedTuple): - condition: Callable[[Rac2Options], bool] - skipped_checks: list[Callable[[CollectionState, int], bool]] - alternative_checks: Optional[list[Callable[[CollectionState, int], bool]]] = None - - def can_dynamo(state: CollectionState, player: int) -> bool: return state.has(Items.DYNAMO.name, player) @@ -84,3 +77,701 @@ def has_hypnomatic_parts(state: CollectionState, player: int) -> bool: FIRST_PERSON_EASY = 1 FIRST_PERSON_MEDIUM = 2 FIRST_PERSON_HARD = 3 + + +def get_options(state: CollectionState, player: int) -> Rac2Options: + return state.multiworld.worlds[player].options + + +def oozla_end_store_cutscene_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return can_dynamo(state, player) + + +def oozla_tractor_puzzle_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return can_tractor(state, player) + + +def oozla_swamp_ruins_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return can_dynamo(state, player) + + +def oozla_swamp_monster_ii_rule(state: CollectionState, player: int) -> bool: + return (can_dynamo(state, player) + and can_gravity(state, player)) + + +def maktar_photo_booth_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return (can_electrolyze(state, player) + or can_heli(state, player)) + + return can_electrolyze(state, player) + + +def maktar_deactivate_jamming_array_rule(state: CollectionState, player: int) -> bool: + return can_tractor(state, player) + + +def maktar_jamming_array_pb_rule(state: CollectionState, player: int) -> bool: + return can_tractor(state, player) + + +def endako_rescue_clank_rule(state: CollectionState, player: int) -> bool: + return can_electrolyze(state, player) + + +def endako_crane_pb_rule(state: CollectionState, player: int) -> bool: + return can_electrolyze(state, player) + + +def endako_crane_nt_rule(state: CollectionState, player: int) -> bool: + return (can_electrolyze(state, player) + and can_infiltrate(state, player)) + + +def barlow_inventor_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return can_swingshot(state, player) + + +def barlow_overbike_race_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return can_electrolyze(state, player) + + return (can_improved_jump(state, player) + and can_electrolyze(state, player)) + + +def barlow_hound_cave_pb_rule(state: CollectionState, player: int) -> bool: + return can_swingshot(state, player) + + +def notak_top_pier_telescreen_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return (can_improved_jump(state, player) + and can_thermanate(state, player)) + + +def notak_worker_bots_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return (can_heli(state, player) + and can_thermanate(state, player)) + + +def notak_timed_dynamo_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return (can_dynamo(state, player) + and can_thermanate(state, player) + and can_improved_jump(state, player)) + + +def siberius_defeat_thief_rule(state: CollectionState, player: int) -> bool: + return can_swingshot(state, player) + + +def siberius_flamebot_ledge_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return can_tractor(state, player) + + +def siberius_fenced_area_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return can_heli(state, player) + + +def tabora_meet_angelar_rule(state: CollectionState, player: int) -> bool: + return (can_heli(state, player) + and can_swingshot(state, player)) + + +def tabora_underground_mines_end_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return (can_heli(state, player) + and can_swingshot(state, player)) + + return (can_heli(state, player) + and can_swingshot(state, player) + and can_thermanate(state, player)) + + +def tabora_canyon_glide_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return (can_heli(state, player) + and can_swingshot(state, player) + and can_glide(state, player)) + + return (can_heli(state, player) + and can_swingshot(state, player) + and can_thermanate(state, player) + and can_glide(state, player)) + + +def tabora_northeast_desert_pb_rule(state: CollectionState, player: int) -> bool: + return (can_heli(state, player) + and can_swingshot(state, player)) + + +def tabora_canyon_glide_pillar_nt_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return (can_heli(state, player) + and can_swingshot(state, player) + and can_glide(state, player)) + + return (can_heli(state, player) + and can_swingshot(state, player) + and can_thermanate(state, player) + and can_glide(state, player)) + + +def dobbo_defeat_thug_leader_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return can_swingshot(state, player) + + return (can_swingshot(state, player) + and can_improved_jump(state, player) + and can_dynamo(state, player)) + + +def dobbo_facility_terminal_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return (can_swingshot(state, player) + and can_glide(state, player) + and can_dynamo(state, player) + and can_electrolyze(state, player)) + + +def dobbo_spiderbot_room_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return can_swingshot(state, player) + + return (can_swingshot(state, player) + and can_dynamo(state, player)) + + +def dobbo_facility_glide_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return (can_swingshot(state, player) + and can_glide(state, player) + and can_dynamo(state, player)) + + +def dobbo_facility_glide_nt_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return (can_swingshot(state, player) + and can_glide(state, player) + and can_dynamo(state, player)) + + +def joba_hoverbike_race_rule(state: CollectionState, player: int) -> bool: + return can_swingshot(state, player) + + +def joba_shady_salesman_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return (can_dynamo(state, player) + and can_improved_jump(state, player)) + + +def joba_arena_battle_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return can_levitate(state, player) + + return (can_dynamo(state, player) + and can_improved_jump(state, player) + and can_levitate(state, player)) + + +def joba_arena_cage_match_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return can_levitate(state, player) + + return (can_dynamo(state, player) + and can_improved_jump(state, player) + and can_levitate(state, player)) + + +def joba_hidden_cliff_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return (can_dynamo(state, player) + and can_swingshot(state, player)) + + +def joba_levitator_tower_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return can_levitate(state, player) + + return (can_dynamo(state, player) + and can_improved_jump(state, player) + and can_levitate(state, player)) + + +def joba_timed_dynamo_nt_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return can_dynamo(state, player) + + +def todano_search_rocket_silo_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return (can_electrolyze(state, player) + and can_improved_jump(state, player) + and can_infiltrate(state, player)) + + +def todano_stuart_zurgo_trade_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + return has_qwark_statuette(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return (can_tractor(state, player) + and has_qwark_statuette(state, player)) + + return (can_electrolyze(state, player) + and can_tractor(state, player) + and has_qwark_statuette(state, player)) + + +def todano_facility_interior_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + return True + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return can_tractor(state, player) + + return (can_electrolyze(state, player) + and can_tractor(state, player)) + + +def todano_near_stuart_zurgo_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + return True + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return can_tractor(state, player) + + return (can_electrolyze(state, player) + and can_tractor(state, player)) + + +def todano_spiderbot_conveyor_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return (can_tractor(state, player) + and can_improved_jump(state, player) + and can_spiderbot(state, player)) + + return (can_electrolyze(state, player) + and can_tractor(state, player) + and can_improved_jump(state, player) + and can_spiderbot(state, player)) + + +def todano_rocket_silo_nt_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return (can_electrolyze(state, player) + and can_infiltrate(state, player)) + + +def boldan_find_fizzwidget_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + return True + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return (can_gravity(state, player) + and can_improved_jump(state, player)) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return (can_swingshot(state, player) + and can_gravity(state, player)) + + return (can_levitate(state, player) + and can_swingshot(state, player) + and can_gravity(state, player)) + + +def boldan_spiderbot_alley_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return (can_levitate(state, player) + and can_spiderbot(state, player)) + + +def boldan_floating_platform_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return can_gravity(state, player) + + return (can_levitate(state, player) + and can_gravity(state, player)) + + +def boldan_fountain_nt_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return can_levitate(state, player) + + +def aranos_control_room_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + return True + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return (can_infiltrate(state, player) + and can_levitate(state, player)) + + return (can_gravity(state, player) + and can_infiltrate(state, player) + and can_levitate(state, player)) + + +def aranos_plumber_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return (can_gravity(state, player) + and can_levitate(state, player)) + + +def aranos_under_ship_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return can_heli(state, player) + + return (can_gravity(state, player) + and can_heli(state, player)) + + +def aranos_omniwrench_12000_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return True + + return can_gravity(state, player) + + +def snivelak_rescue_angelak_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >+ FIRST_PERSON_EASY: + return can_swingshot(state, player) + + return (can_swingshot(state, player) + and can_grind(state, player) + and can_gravity(state, player) + and can_dynamo(state, player)) + + +def snivelak_dynamo_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return can_swingshot(state, player) + + return (can_swingshot(state, player) + and can_grind(state, player) + and can_gravity(state, player) + and can_dynamo(state, player) + and can_heli(state, player)) + + +def snivelak_swingshot_tower_nt_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return can_swingshot(state, player) + + return (can_swingshot(state, player) + and can_heli(state, player)) + + +def smolg_balloon_transmission_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return can_electrolyze(state, player) + + return (can_improved_jump(state, player) + and can_dynamo(state, player) + and can_electrolyze(state, player)) + + +def smolg_distribution_facility_end_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return can_electrolyze(state, player) + + return (can_improved_jump(state, player) + and can_dynamo(state, player) + and can_electrolyze(state, player) + and can_grind(state, player) + and can_infiltrate(state, player)) + + +def smolg_mutant_crab_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if not can_levitate(state, player): + return False + return (can_swingshot(state, player) + or can_electrolyze(state, player)) + + return (can_swingshot(state, player) + and can_levitate(state, player)) + + +def smolg_floating_platform_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if not can_levitate(state, player): + return False + return (can_swingshot(state, player) + or can_electrolyze(state, player)) + + return (can_swingshot(state, player) + and can_levitate(state, player)) + + +def smolg_warehouse_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return (can_dynamo(state, player) + or can_improved_jump(state, player)) + + +def damosel_hypnotist_rule(state: CollectionState, player: int) -> bool: + return (can_swingshot(state, player) + and can_improved_jump(state, player) + and can_thermanate(state, player) + and has_hypnomatic_parts(state, player)) + + +def damosel_train_rails_rule(state: CollectionState, player: int) -> bool: + return can_grind(state, player) + + +def damosel_frozen_mountain_pb_rule(state: CollectionState, player: int) -> bool: + return (can_swingshot(state, player) + and can_improved_jump(state, player) + and can_thermanate(state, player) + and can_grind(state, player)) + + +def damosel_pyramid_pb_rule(state: CollectionState, player: int) -> bool: + return (can_swingshot(state, player) + and can_improved_jump(state, player) + and can_hypnotize(state, player)) + + +def grelbin_find_angela_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return can_hypnotize(state, player) + + +def grelbin_mystic_more_moonstones_rule(state: CollectionState, player: int) -> bool: + return (can_glide(state, player) + and can_infiltrate(state, player)) + + +def grelbin_ice_plains_pb_rule(state: CollectionState, player: int) -> bool: + return (can_glide(state, player) + and can_infiltrate(state, player)) + + +def grelbin_underwater_tunnel_pb_rule(state: CollectionState, player: int) -> bool: + return can_hypnotize(state, player) + + +def grelbin_yeti_cave_pb_rule(state: CollectionState, player: int) -> bool: + return (can_glide(state, player) + and can_infiltrate(state, player) + and can_hypnotize(state, player)) + + +def yeedil_defeat_mutated_protopet_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + return can_infiltrate(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return (can_hypnotize(state, player) + and can_swingshot(state, player) + and can_infiltrate(state, player)) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return (can_hypnotize(state, player) + and can_swingshot(state, player) + and can_infiltrate(state, player) + and can_dynamo(state, player) + and can_improved_jump(state, player)) + + return (can_hypnotize(state, player) + and can_swingshot(state, player) + and can_infiltrate(state, player) + and can_dynamo(state, player) + and can_improved_jump(state, player) + and can_electrolyze(state, player)) + + +def yeedil_bridge_grindrail_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return True + + return can_grind(state, player) + + +def yeedil_tractor_pillar_pb_rule(state: CollectionState, player: int) -> bool: + options = get_options(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + return can_infiltrate(state, player) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + return (can_hypnotize(state, player) + and can_swingshot(state, player) + and can_infiltrate(state, player)) + + if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + return (can_hypnotize(state, player) + and can_swingshot(state, player) + and can_infiltrate(state, player) + and can_dynamo(state, player) + and can_improved_jump(state, player) + and can_tractor(state, player) + and can_grind(state, player)) + + return (can_hypnotize(state, player) + and can_swingshot(state, player) + and can_infiltrate(state, player) + and can_dynamo(state, player) + and can_improved_jump(state, player) + and can_electrolyze(state, player) + and can_tractor(state, player) + and can_grind(state, player)) \ No newline at end of file diff --git a/Regions.py b/Regions.py index 9eb1146..6e2dd1d 100644 --- a/Regions.py +++ b/Regions.py @@ -55,19 +55,8 @@ def planet_access_rule(state: CollectionState): def generate_access_rule(loc: LocationData) -> typing.Callable[[CollectionState], bool]: def access_rule(state: CollectionState): - if loc.vanilla_requirements: - requirements = loc.vanilla_requirements - if loc.alternative_routes: - for route in loc.alternative_routes: - if route.condition(state.multiworld.worlds[world.player].options): - requirements = [req for req in requirements if req not in route.skipped_checks] - if route.alternative_checks: - requirements.extend(route.alternative_checks) - for requirement in requirements: - if not requirement(state, world.player): - return False - return True - + if loc.access_rule: + return loc.access_rule(state, world.player) return True return access_rule diff --git a/data/Locations.py b/data/Locations.py index 07f461d..2d64628 100644 --- a/data/Locations.py +++ b/data/Locations.py @@ -8,8 +8,7 @@ class LocationData(NamedTuple): location_id: Optional[int] name: str - vanilla_requirements: Optional[list[Callable[[CollectionState, int], bool]]] = None - alternative_routes: Optional[list[AlternativeRoute]] = None + access_rule: Optional[Callable[[CollectionState, int], bool]] = None checked_flag_address: Optional[Callable[["Addresses"], int]] = None enable_if: Optional[Callable[[Dict[str, Any]], bool]] = None is_vendor: bool = False @@ -17,93 +16,33 @@ class LocationData(NamedTuple): """ Oozla """ OOZLA_OUTSIDE_MEGACORP_STORE = LocationData(10, "Oozla: Outside Megacorp Store - Dynamo") -OOZLA_END_STORE_CUTSCENE = LocationData( - 11, "Oozla: End of Store Cutscene", - vanilla_requirements=[can_dynamo], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo] - ) - ] -) +OOZLA_END_STORE_CUTSCENE = LocationData(11, "Oozla: End of Store Cutscene", oozla_end_store_cutscene_rule) OOZLA_MEGACORP_SCIENTIST = LocationData(12, "Oozla: Megacorp Scientist - Tractor Beam") -OOZLA_TRACTOR_PUZZLE_PB = LocationData( - 13, "Oozla: Tractor Puzzle - Platinum Bolt", - vanilla_requirements=[can_tractor], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_tractor] - ) - ] -) -OOZLA_SWAMP_RUINS_PB = LocationData( - 14, "Oozla: Swamp Ruins - Platinum Bolt", - vanilla_requirements=[can_dynamo], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo] - ) - ] -) -OOZLA_SWAMP_MONSTER_II = LocationData( - 15, "Oozla: Swamp Monster II - Box Breaker", - vanilla_requirements=[can_dynamo, can_gravity] -) +OOZLA_TRACTOR_PUZZLE_PB = LocationData(13, "Oozla: Tractor Puzzle - Platinum Bolt", oozla_tractor_puzzle_pb_rule) +OOZLA_SWAMP_RUINS_PB = LocationData(14, "Oozla: Swamp Ruins - Platinum Bolt", oozla_swamp_ruins_pb_rule) +OOZLA_SWAMP_MONSTER_II = LocationData(15, "Oozla: Swamp Monster II - Box Breaker",oozla_swamp_monster_ii_rule) """ Maktar """ MAKTAR_ARENA_CHALLENGE = LocationData(20, "Maktar: Arena Challenge - Electrolyzer") -MAKTAR_PHOTO_BOOTH = LocationData( - 21, "Maktar: Photo Booth", - vanilla_requirements=[can_electrolyze], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_electrolyze], - alternative_checks=[can_heli] - ) - ] -) -MAKTAR_DEACTIVATE_JAMMING_ARRAY = LocationData(22, "Maktar: Deactivate Jamming Array", [can_tractor]) -MAKTAR_JAMMING_ARRAY_PB = LocationData(23, "Maktar: Jamming Array - Platinum Bolt", [can_tractor]) +MAKTAR_PHOTO_BOOTH = LocationData(21, "Maktar: Photo Booth", maktar_photo_booth_rule) +MAKTAR_DEACTIVATE_JAMMING_ARRAY = LocationData(22, "Maktar: Deactivate Jamming Array", maktar_deactivate_jamming_array_rule) +MAKTAR_JAMMING_ARRAY_PB = LocationData(23, "Maktar: Jamming Array - Platinum Bolt", maktar_jamming_array_pb_rule) MAKTAR_CRANE_PB = LocationData(24, "Maktar: Crane - Platinum Bolt") """ Endako """ ENDAKO_CLANK_APARTMENT_SS = LocationData(30, "Endako: Clank's Apartment - Swingshot") ENDAKO_CLANK_APARTMENT_GB = LocationData(31, "Endako: Clank's Apartment - Grindboots") -ENDAKO_RESCUE_CLANK_HELI = LocationData(32, "Endako: Rescue Clank Heli-Pack", [can_electrolyze]) -ENDAKO_RESCUE_CLANK_THRUSTER = LocationData(33, "Endako: Rescue Clank Thruster-Pack", [can_electrolyze]) +ENDAKO_RESCUE_CLANK_HELI = LocationData(32, "Endako: Rescue Clank Heli-Pack", endako_rescue_clank_rule) +ENDAKO_RESCUE_CLANK_THRUSTER = LocationData(33, "Endako: Rescue Clank Thruster-Pack", endako_rescue_clank_rule) ENDAKO_LEDGE_PB = LocationData(34, "Endako: Ledge - Platinum Bolt") -ENDAKO_CRANE_PB = LocationData(35, "Endako: Crane - Platinum Bolt", [can_electrolyze]) -ENDAKO_CRANE_NT = LocationData(36, "Endako: Crane - Nanotech Boost", [can_electrolyze, can_infiltrate]) +ENDAKO_CRANE_PB = LocationData(35, "Endako: Crane - Platinum Bolt", endako_crane_pb_rule) +ENDAKO_CRANE_NT = LocationData(36, "Endako: Crane - Nanotech Boost", endako_crane_nt_rule) """ Barlow """ -BARLOW_INVENTOR = LocationData( - 40, "Barlow: Inventor - Thermanator", - vanilla_requirements=[can_swingshot], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_swingshot] - ) - ] -) -BARLOW_HOVERBIKE_RACE_TRANSMISSION = LocationData( - 41, "Barlow: Hoverbike Race Transmission", - vanilla_requirements=[can_electrolyze, can_improved_jump], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_improved_jump] - ) - ] -) -BARLOW_HOVERBIKE_RACE_PB = LocationData( - 42, "Barlow: Hoverbike Race - Platinum Bolt", - vanilla_requirements=[can_electrolyze, can_improved_jump], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_improved_jump] - ) - ] -) -BARLOW_HOUND_CAVE_PB = LocationData(43, "Barlow: Hound Cave - Platinum Bolt", [can_swingshot]) +BARLOW_INVENTOR = LocationData(40, "Barlow: Inventor - Thermanator", barlow_inventor_rule) +BARLOW_HOVERBIKE_RACE_TRANSMISSION = LocationData(41, "Barlow: Hoverbike Race Transmission", barlow_overbike_race_rule) +BARLOW_HOVERBIKE_RACE_PB = LocationData(42, "Barlow: Hoverbike Race - Platinum Bolt", barlow_overbike_race_rule) +BARLOW_HOUND_CAVE_PB = LocationData(43, "Barlow: Hound Cave - Platinum Bolt", barlow_hound_cave_pb_rule) """ Feltzin System """ FELTZIN_DEFEAT_THUG_SHIPS = LocationData(50, "Feltzin: Defeat Thug Ships") @@ -126,146 +65,36 @@ class LocationData(NamedTuple): ) """ Notak """ -NOTAK_TOP_PIER_TELESCREEN = LocationData( - 60, "Notak: Top of Pier Telescreen", - vanilla_requirements=[can_improved_jump, can_thermanate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_improved_jump, can_thermanate] - ) - ] -) -NOTAK_WORKER_BOTS = LocationData( - 61, "Notak: Worker Bots", - vanilla_requirements=[can_heli, can_thermanate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_heli, can_thermanate] - ) - ] -) +NOTAK_TOP_PIER_TELESCREEN = LocationData(60, "Notak: Top of Pier Telescreen", notak_top_pier_telescreen_rule) +NOTAK_WORKER_BOTS = LocationData(61, "Notak: Worker Bots", notak_worker_bots_rule) NOTAK_BEHIND_BUILDING_PB = LocationData(62, "Notak: Behind Building - Platinum Bolt") NOTAK_PROMENADE_SIGN_PB = LocationData(63, "Notak: Promenade Sign - Platinum Bolt") -NOTAK_TIMED_DYNAMO_PB = LocationData( - 64, "Notak: Timed Dynamo - Platinum Bolt", - vanilla_requirements=[can_improved_jump, can_thermanate, can_dynamo], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_improved_jump, can_thermanate, can_dynamo] - ) - ] -) +NOTAK_TIMED_DYNAMO_PB = LocationData(64, "Notak: Timed Dynamo - Platinum Bolt", notak_timed_dynamo_rule) NOTAK_PROMENADE_END_NT = LocationData(65, "Notak: Promenade End - Nanotech Boost") """ Siberius """ -SIBERIUS_DEFEAT_THIEF = LocationData(70, "Siberius: Defeat Thief", [can_swingshot]) -SIBERIUS_FLAMEBOT_LEDGE_PB = LocationData( - 71, "Siberius: Flamebot Ledge - Platinum Bolt", - vanilla_requirements=[can_tractor], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_tractor] - ) - ] -) -SIBERIUS_FENCED_AREA_PB = LocationData( - 72, "Siberius: Fenced Area - Platinum Bolt", - vanilla_requirements=[can_heli], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_heli] - ) - ] -) +SIBERIUS_DEFEAT_THIEF = LocationData(70, "Siberius: Defeat Thief", siberius_defeat_thief_rule) +SIBERIUS_FLAMEBOT_LEDGE_PB = LocationData(71, "Siberius: Flamebot Ledge - Platinum Bolt", siberius_flamebot_ledge_pb_rule) +SIBERIUS_FENCED_AREA_PB = LocationData(72, "Siberius: Fenced Area - Platinum Bolt", siberius_fenced_area_pb_rule) """ Tabora """ -TABORA_MEET_ANGELA = LocationData(80, "Tabora: Meet Angela", [can_heli, can_swingshot]) -TABORA_UNDERGROUND_MINES_END = LocationData( - 81, "Tabora: Underground Mines - Glider", - vanilla_requirements=[can_heli, can_swingshot, can_thermanate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_thermanate] - ) - ] -) -TABORA_UNDERGROUND_MINES_PB = LocationData( - 82, "Tabora: Underground Mines - Platinum Bolt", - vanilla_requirements=[can_heli, can_swingshot, can_thermanate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_thermanate] - ) - ] -) -TABORA_CANYON_GLIDE_PB = LocationData( - 83, "Tabora: Canyon Glide - Platinum Bolt", - vanilla_requirements=[can_heli, can_swingshot, can_thermanate, can_glide], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_thermanate] - ) - ] -) -TABORA_NORTHEAST_DESERT_PB = LocationData(84, "Tabora: Northeast Desert - Platinum Bolt", [can_heli, can_swingshot]) -TABORA_CANYON_GLIDE_PILLAR_NT = LocationData( - 85, "Tabora: Canyon Glide Pillar - Nanotech Boost", - vanilla_requirements=[can_heli, can_swingshot, can_thermanate, can_glide], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_thermanate] - ) - ] -) +TABORA_MEET_ANGELA = LocationData(80, "Tabora: Meet Angela", tabora_meet_angelar_rule) +TABORA_UNDERGROUND_MINES_END = LocationData(81, "Tabora: Underground Mines - Glider", tabora_underground_mines_end_rule) +TABORA_UNDERGROUND_MINES_PB = LocationData(82, "Tabora: Underground Mines - Platinum Bolt", tabora_underground_mines_end_rule) +TABORA_CANYON_GLIDE_PB = LocationData(83, "Tabora: Canyon Glide - Platinum Bolt", tabora_canyon_glide_pb_rule) +TABORA_NORTHEAST_DESERT_PB = LocationData(84, "Tabora: Northeast Desert - Platinum Bolt", tabora_northeast_desert_pb_rule) +TABORA_CANYON_GLIDE_PILLAR_NT = LocationData(85, "Tabora: Canyon Glide Pillar - Nanotech Boost", tabora_canyon_glide_pillar_nt_rule) TABORA_OMNIWRENCH_10000 = LocationData( 86, "Tabora: OmniWrench 10000", checked_flag_address=lambda ram: ram.tabora_wrench_cutscene_flag ) """ Dobbo """ -DOBBO_DEFEAT_THUG_LEADER = LocationData( - 90, "Dobbo: Defeat Thug Leader", - vanilla_requirements=[can_swingshot, can_improved_jump, can_dynamo], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_improved_jump, can_dynamo] - ) - ] -) -DOBBO_FACILITY_TERMINAL = LocationData( - 91, "Dobbo: Facility Terminal", - vanilla_requirements=[can_swingshot, can_glide, can_dynamo, can_electrolyze], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_swingshot, can_glide, can_dynamo, can_electrolyze] - ) - ] -) -DOBBO_SPIDERBOT_ROOM_PB = LocationData( - 92, "Dobbo: Spiderbot Room - Platinum Bolt", - vanilla_requirements=[can_swingshot, can_dynamo, can_spiderbot], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_dynamo, can_spiderbot] - ) - ] -) -DOBBO_FACILITY_GLIDE_PB = LocationData( - 93, "Dobbo: Facility Glide End - Platinum Bolt", - vanilla_requirements=[can_swingshot, can_dynamo, can_glide], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_swingshot, can_dynamo, can_glide]) - ] -) -DOBBO_FACILITY_GLIDE_NT = LocationData( - 94, "Dobbo: Facility Glide Beginning - Nanotech Boost", - vanilla_requirements=[can_swingshot, can_dynamo, can_glide], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_swingshot, can_dynamo, can_glide]) - ] -) +DOBBO_DEFEAT_THUG_LEADER = LocationData(90, "Dobbo: Defeat Thug Leader", dobbo_defeat_thug_leader_rule) +DOBBO_FACILITY_TERMINAL = LocationData(91, "Dobbo: Facility Terminal", dobbo_facility_terminal_rule) +DOBBO_SPIDERBOT_ROOM_PB = LocationData(92, "Dobbo: Spiderbot Room - Platinum Bolt", dobbo_spiderbot_room_pb_rule) +DOBBO_FACILITY_GLIDE_PB = LocationData(93, "Dobbo: Facility Glide End - Platinum Bolt", dobbo_facility_glide_pb_rule) +DOBBO_FACILITY_GLIDE_NT = LocationData(94, "Dobbo: Facility Glide Beginning - Nanotech Boost", dobbo_facility_glide_nt_rule) """ Hrugis """ HRUGIS_DESTROY_DEFENSES = LocationData(100, "Hrugis Cloud: Destroy Defenses") @@ -287,235 +116,36 @@ class LocationData(NamedTuple): ) """ Joba """ -JOBA_FIRST_HOVERBIKE_RACE = LocationData(110, "Joba: First Hoverbike Race - Charge Boots", [can_swingshot]) -JOBA_SHADY_SALESMAN = LocationData( - 111, "Joba: Shady Salesman - Levitator", - vanilla_requirements=[can_dynamo, can_improved_jump], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo, can_improved_jump] - ) - ] -) -JOBA_ARENA_BATTLE = LocationData( - 112, "Joba: Arena Battle - Gravity Boots", - vanilla_requirements=[can_dynamo, can_improved_jump, can_levitate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo, can_improved_jump] - ) - ] -) -JOBA_ARENA_CAGE_MATCH = LocationData( - 113, "Joba: Arena Cage Match - Infiltrator", - vanilla_requirements=[can_dynamo, can_improved_jump, can_levitate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo, can_improved_jump] - ) - ] -) -JOBA_HIDDEN_CLIFF_PB = LocationData( - 114, "Joba: Hidden Cliff - Platinum Bolt", - vanilla_requirements=[can_dynamo, can_improved_jump], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo, can_improved_jump] - ) - ] -) -JOBA_LEVITATOR_TOWER_PB = LocationData( - 115, "Joba: Levitator Tower - Platinum Bolt", - vanilla_requirements=[can_dynamo, can_improved_jump, can_levitate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo, can_improved_jump] - ) - ] -) -JOBA_HOVERBIKE_RACE_SHORTCUT_NT = LocationData(116, "Joba: Hoverbike Race Shortcut - Nanotech Boost", [can_swingshot]) -JOBA_TIMED_DYNAMO_NT = LocationData( - 117, "Joba: Timed Dynamo Course - Nanotech Boost", - vanilla_requirements=[can_dynamo], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo] - ) - ] -) +JOBA_FIRST_HOVERBIKE_RACE = LocationData(110, "Joba: First Hoverbike Race - Charge Boots", joba_hoverbike_race_rule) +JOBA_SHADY_SALESMAN = LocationData(111, "Joba: Shady Salesman - Levitator", joba_shady_salesman_rule) +JOBA_ARENA_BATTLE = LocationData(112, "Joba: Arena Battle - Gravity Boots", joba_arena_battle_rule) +JOBA_ARENA_CAGE_MATCH = LocationData(113, "Joba: Arena Cage Match - Infiltrator", joba_arena_cage_match_rule) +JOBA_HIDDEN_CLIFF_PB = LocationData(114, "Joba: Hidden Cliff - Platinum Bolt", joba_hidden_cliff_pb_rule) +JOBA_LEVITATOR_TOWER_PB = LocationData(115, "Joba: Levitator Tower - Platinum Bolt", joba_levitator_tower_pb_rule) +JOBA_HOVERBIKE_RACE_SHORTCUT_NT = LocationData(116, "Joba: Hoverbike Race Shortcut - Nanotech Boost", joba_hoverbike_race_rule) +JOBA_TIMED_DYNAMO_NT = LocationData(117, "Joba: Timed Dynamo Course - Nanotech Boost", joba_timed_dynamo_nt_rule) """ Todano """ -TODANO_SEARCH_ROCKET_SILO = LocationData( - 120, "Todano: Search Rocket Silo", - vanilla_requirements=[can_electrolyze, can_improved_jump, can_infiltrate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_electrolyze, can_improved_jump, can_infiltrate] - ) - ] -) -TODANO_STUART_ZURGO_TRADE = LocationData( - 121, "Todano: Stuart Zurgo Trade - Armor Magnetizer", - vanilla_requirements=[can_tractor, can_electrolyze, has_qwark_statuette], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, - [can_tractor, can_electrolyze] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_electrolyze] - ) - ] -) -TODANO_FACILITY_INTERIOR = LocationData( - 122, "Todano: Facility Interior - Sheepinator", - vanilla_requirements=[can_tractor, can_electrolyze], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, - [can_tractor, can_electrolyze] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_electrolyze] - ) - ] -) -TODANO_NEAR_STUART_ZURGO_PB = LocationData( - 123, "Todano: Near Stuart Zurgo - Platinum Bolt", - vanilla_requirements=[can_tractor, can_electrolyze], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, - [can_tractor, can_electrolyze] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_electrolyze] - ) - ] -) +TODANO_SEARCH_ROCKET_SILO = LocationData(120, "Todano: Search Rocket Silo", todano_search_rocket_silo_rule) +TODANO_STUART_ZURGO_TRADE = LocationData(121, "Todano: Stuart Zurgo Trade - Armor Magnetizer", todano_stuart_zurgo_trade_rule) +TODANO_FACILITY_INTERIOR = LocationData(122, "Todano: Facility Interior - Sheepinator", todano_facility_interior_rule) +TODANO_NEAR_STUART_ZURGO_PB = LocationData(123, "Todano: Near Stuart Zurgo - Platinum Bolt", todano_near_stuart_zurgo_pb_rule) TODANO_END_TOUR_PB = LocationData(124, "Todano: End of Tour - Platinum Bolt") -TODANO_SPIDERBOT_CONVEYOR_PB = LocationData( - 125, "Todano: Spiderbot Conveyor - Platinum Bolt", - vanilla_requirements=[can_electrolyze, can_tractor, can_improved_jump, can_spiderbot], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, - [can_electrolyze, can_tractor] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_electrolyze] - ) - ] -) -TODANO_ROCKET_SILO_NT = LocationData( - 126, "Todano: Rocket Silo - Nanotech Boost", - vanilla_requirements=[can_electrolyze, can_infiltrate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_electrolyze, can_infiltrate] - ) - ] -) +TODANO_SPIDERBOT_CONVEYOR_PB = LocationData(125, "Todano: Spiderbot Conveyor - Platinum Bolt", todano_spiderbot_conveyor_pb_rule) +TODANO_ROCKET_SILO_NT = LocationData(126, "Todano: Rocket Silo - Nanotech Boost", todano_rocket_silo_nt_rule) """ Boldan """ -BOLDAN_FIND_FIZZWIDGET = LocationData( - 130, "Boldan: Find Fizzwidget", - vanilla_requirements=[can_levitate, can_swingshot, can_gravity], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, - [can_levitate, can_swingshot, can_gravity] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_levitate, can_swingshot], - alternative_checks=[can_improved_jump] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_levitate] - ) - ] -) -BOLDAN_SPIDERBOT_ALLEY_PB = LocationData( - 131, "Boldan: Spiderbot Alley - Platinum Bolt", - vanilla_requirements=[can_levitate, can_spiderbot], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_levitate, can_spiderbot] - ) - ] -) -BOLDAN_FLOATING_PLATFORM_PB = LocationData( - 132, "Boldan: Floating Platform - Platinum Bolt", - vanilla_requirements=[can_levitate, can_gravity], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_levitate, can_gravity] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_levitate] - ) - ] -) -BOLDAN_UPPER_DOME_PB = LocationData( - 133, "Boldan: Upper Dome - Platinum Bolt", - vanilla_requirements=[can_levitate, can_swingshot, can_gravity], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, - [can_levitate, can_swingshot, can_gravity] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_levitate, can_swingshot], - alternative_checks=[can_improved_jump] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_levitate] - ) - ] -) -BOLDAN_FOUNTAIN_NT = LocationData( - 134, "Boldan: Fountain - Nanotech Boost", - vanilla_requirements=[can_levitate, can_spiderbot], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_levitate, can_spiderbot] - ) - ] -) +BOLDAN_FIND_FIZZWIDGET = LocationData(130, "Boldan: Find Fizzwidget", boldan_find_fizzwidget_rule) +BOLDAN_SPIDERBOT_ALLEY_PB = LocationData(131, "Boldan: Spiderbot Alley - Platinum Bolt", boldan_spiderbot_alley_pb_rule) +BOLDAN_FLOATING_PLATFORM_PB = LocationData(132, "Boldan: Floating Platform - Platinum Bolt",boldan_floating_platform_rule) +BOLDAN_UPPER_DOME_PB = LocationData(133, "Boldan: Upper Dome - Platinum Bolt", boldan_find_fizzwidget_rule) +BOLDAN_FOUNTAIN_NT = LocationData(134, "Boldan: Fountain - Nanotech Boost", boldan_fountain_nt_rule) """ Aranos Prison """ -ARANOS_CONTROL_ROOM = LocationData( - 140, "Aranos: Control Room", - vanilla_requirements=[can_gravity, can_infiltrate, can_levitate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, - [can_gravity, can_infiltrate, can_levitate] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_gravity] - ) - ] -) -ARANOS_PLUMBER = LocationData( - 141, "Aranos: Plumber - Qwark Statuette", - vanilla_requirements=[can_gravity, can_levitate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_gravity, can_levitate] - ) - ] -) -ARANOS_UNDER_SHIP_PB = LocationData( - 142, "Aranos: Under Ship - Platinum Bolt", - vanilla_requirements=[can_gravity, can_heli], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_gravity] - ) - ] -) -ARANOS_OMNIWRENCH_12000 = LocationData( - 143, "Aranos: OmniWrench 12000", - vanilla_requirements=[can_gravity], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_gravity] - ) - ], +ARANOS_CONTROL_ROOM = LocationData(140, "Aranos: Control Room", aranos_control_room_rule) +ARANOS_PLUMBER = LocationData(141, "Aranos: Plumber - Qwark Statuette", aranos_plumber_rule) +ARANOS_UNDER_SHIP_PB = LocationData(142, "Aranos: Under Ship - Platinum Bolt", aranos_under_ship_pb_rule) +ARANOS_OMNIWRENCH_12000 = LocationData(143, "Aranos: OmniWrench 12000", aranos_omniwrench_12000_rule, checked_flag_address=lambda ram: ram.aranos_wrench_cutscene_flag ) @@ -539,154 +169,41 @@ class LocationData(NamedTuple): ) """ Snivelak """ -SNIVELAK_RESCUE_ANGELA = LocationData( - 160, "Snivelak: Rescue Angela", - vanilla_requirements=[can_swingshot, can_grind, can_gravity, can_dynamo], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_grind, can_gravity, can_dynamo] - ) - ] -) -SNIVELAK_DYNAMO_PLATFORMS_PB = LocationData( - 161, "Snivelak: Dynamo Platforms - Platinum Bolt", - vanilla_requirements=[can_swingshot, can_grind, can_gravity, can_dynamo, can_heli], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_grind, can_gravity, can_dynamo, can_heli] - ) - ] -) -SNIVELAK_SWINGSHOT_TOWER_NT = LocationData( - 162, "Snivelak: Swingshot Tower - Nanotech Boost", - vanilla_requirements=[can_swingshot, can_heli], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_heli] - ) - ] -) +SNIVELAK_RESCUE_ANGELA = LocationData(160, "Snivelak: Rescue Angela", snivelak_rescue_angelak_rule) +SNIVELAK_DYNAMO_PLATFORMS_PB = LocationData(161, "Snivelak: Dynamo Platforms - Platinum Bolt", snivelak_dynamo_pb_rule) +SNIVELAK_SWINGSHOT_TOWER_NT = LocationData(162, "Snivelak: Swingshot Tower - Nanotech Boost", snivelak_swingshot_tower_nt_rule) """ Smolg """ -SMOLG_BALLOON_TRANSMISSION = LocationData( - 170, "Smolg: Balloon Transmission", - vanilla_requirements=[can_improved_jump, can_dynamo, can_electrolyze], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_improved_jump, can_dynamo] - ) - ] -) -SMOLG_DISTRIBUTION_FACILITY_END = LocationData( - 171, "Smolg: Distribution Facility End - Hypnomatic Part", - vanilla_requirements=[can_improved_jump, can_dynamo, can_electrolyze, can_grind, can_infiltrate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_improved_jump, can_dynamo, can_grind, can_infiltrate] - ) - ], +SMOLG_BALLOON_TRANSMISSION = LocationData(170, "Smolg: Balloon Transmission", smolg_balloon_transmission_rule) +SMOLG_DISTRIBUTION_FACILITY_END = LocationData(171, "Smolg: Distribution Facility End - Hypnomatic Part", smolg_distribution_facility_end_rule, checked_flag_address=lambda ram: ram.hypnomatic_part1 ) -SMOLG_MUTANT_CRAB = LocationData( - 172, "Smolg: Mutant Crab", - vanilla_requirements=[can_swingshot, can_levitate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_swingshot], - alternative_checks=[can_electrolyze] - ) - ] -) -SMOLG_FLOATING_PLATFORM_PB = LocationData( - 173, "Smolg: Floating Platform - Platinum Bolt", - vanilla_requirements=[can_swingshot, can_levitate], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_swingshot], - alternative_checks=[can_electrolyze] - ) - ] -) -SMOLG_WAREHOUSE_PB = LocationData( - 174, "Smolg: Warehouse - Platinum Bolt", - vanilla_requirements=[can_dynamo, can_improved_jump], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_dynamo, can_improved_jump] - ) - ] -) +SMOLG_MUTANT_CRAB = LocationData(172, "Smolg: Mutant Crab", smolg_mutant_crab_rule) +SMOLG_FLOATING_PLATFORM_PB = LocationData(173, "Smolg: Floating Platform - Platinum Bolt", smolg_floating_platform_pb_rule) +SMOLG_WAREHOUSE_PB = LocationData(174, "Smolg: Warehouse - Platinum Bolt", smolg_warehouse_pb_rule) """ Damosel """ -DAMOSEL_HYPNOTIST = LocationData(180, "Damosel: Hypnotist", [can_swingshot, can_improved_jump, can_thermanate, has_hypnomatic_parts]) -DAMOSEL_TRAIN_RAILS = LocationData( - 181, "Damosel: Train Rails - Hypnomatic Part", - vanilla_requirements=[can_grind], +DAMOSEL_HYPNOTIST = LocationData(180, "Damosel: Hypnotist", damosel_hypnotist_rule) +DAMOSEL_TRAIN_RAILS = LocationData(181, "Damosel: Train Rails - Hypnomatic Part", damosel_train_rails_rule, checked_flag_address=lambda ram: ram.hypnomatic_part2 ) DAMOSEL_DEFEAT_MOTHERSHIP = LocationData(182, "Damosel: Defeat Mothership - Mapper") -DAMOSEL_FROZEN_FOUNTAIN_PB = LocationData(183, "Damosel: Frozen Fountain - Platinum Bolt", [can_swingshot, can_improved_jump, can_thermanate, can_grind]) -DAMOSEL_PYRAMID_PB = LocationData(184, "Damosel: Pyramid - Platinum Bolt", [can_swingshot, can_improved_jump, can_hypnotize]) +DAMOSEL_FROZEN_FOUNTAIN_PB = LocationData(183, "Damosel: Frozen Fountain - Platinum Bolt", damosel_frozen_mountain_pb_rule) +DAMOSEL_PYRAMID_PB = LocationData(184, "Damosel: Pyramid - Platinum Bolt", damosel_pyramid_pb_rule) """ Grelbin """ -GRELBIN_FIND_ANGELA = LocationData( - 190, "Grelbin: Find Angela", - vanilla_requirements=[can_hypnotize], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_hypnotize] - ) - ] -) -GRELBIN_MYSTIC_MORE_MOONSTONES = LocationData( - 191, "Grelbin: Mystic More Moonstones - Hypnomatic Part", - vanilla_requirements=[can_glide, can_infiltrate], +GRELBIN_FIND_ANGELA = LocationData(190, "Grelbin: Find Angela", grelbin_find_angela_rule) +GRELBIN_MYSTIC_MORE_MOONSTONES = LocationData(191, "Grelbin: Mystic More Moonstones - Hypnomatic Part", grelbin_mystic_more_moonstones_rule, checked_flag_address=lambda ram: ram.hypnomatic_part3 ) -GRELBIN_ICE_PLAINS_PB = LocationData(192, "Grelbin: Ice Plains - Platinum Bolt", [can_glide, can_infiltrate]) -GRELBIN_UNDERWATER_TUNNEL_PB = LocationData(193, "Grelbin: Underwater Tunnel - Platinum Bolt", [can_hypnotize]) -GRELBIN_YETI_CAVE_PB = LocationData(194, "Grelbin: Yeti Cave - Platinum Bolt", [can_glide, can_infiltrate, can_hypnotize]) +GRELBIN_ICE_PLAINS_PB = LocationData(192, "Grelbin: Ice Plains - Platinum Bolt", grelbin_ice_plains_pb_rule) +GRELBIN_UNDERWATER_TUNNEL_PB = LocationData(193, "Grelbin: Underwater Tunnel - Platinum Bolt", grelbin_underwater_tunnel_pb_rule) +GRELBIN_YETI_CAVE_PB = LocationData(194, "Grelbin: Yeti Cave - Platinum Bolt", grelbin_yeti_cave_pb_rule) """ Yeedil """ -YEEDIL_DEFEAT_MUTATED_PROTOPET = LocationData( - None, "Yeedil: Defeat Mutated Protopet", - vanilla_requirements=[can_hypnotize, can_swingshot, can_dynamo, can_infiltrate, can_electrolyze, can_improved_jump], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, - [can_hypnotize, can_swingshot, can_dynamo, can_electrolyze, can_improved_jump] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo, can_improved_jump] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_improved_jump] - ) - ] -) -YEEDIL_BRIDGE_GRINDRAIL_PB = LocationData( - 200, "Yeedil: Bridge Grindrail - Platinum Bolt", - vanilla_requirements=[can_grind], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_grind] - ) - ] -) -YEEDIL_TRACTOR_PILLAR_PB = LocationData( - 201, "Yeedil: Tractor Pillar - Platinum Bolt", - vanilla_requirements=[can_hypnotize, can_swingshot, can_dynamo, can_infiltrate, can_electrolyze, can_improved_jump, can_tractor, can_grind], - alternative_routes=[ - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD, - [can_hypnotize, can_swingshot, can_dynamo, can_electrolyze, can_improved_jump, can_tractor, can_grind] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM, - [can_dynamo, can_improved_jump, can_tractor, can_grind] - ), - AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY, - [can_improved_jump] - ) - ] -) +YEEDIL_DEFEAT_MUTATED_PROTOPET = LocationData(None, "Yeedil: Defeat Mutated Protopet", yeedil_defeat_mutated_protopet_rule) +YEEDIL_BRIDGE_GRINDRAIL_PB = LocationData(200, "Yeedil: Bridge Grindrail - Platinum Bolt", yeedil_bridge_grindrail_pb_rule) +YEEDIL_TRACTOR_PILLAR_PB = LocationData(201, "Yeedil: Tractor Pillar - Platinum Bolt", yeedil_tractor_pillar_pb_rule) """ Megacorp Vendor """ OOZLA_VENDOR_WEAPON_1 = LocationData( From 4652d29481345b2f6d4c33b053a922f971279572 Mon Sep 17 00:00:00 2001 From: Pecomare Date: Wed, 26 Mar 2025 22:50:28 +0100 Subject: [PATCH 4/5] Remove allow_first_person_mode option and force allow it --- Container.py | 7 +++---- Rac2Options.py | 6 ------ Simplified Ratchet & Clank 2.yaml | 3 --- __init__.py | 6 +----- 4 files changed, 4 insertions(+), 18 deletions(-) diff --git a/Container.py b/Container.py index f19bd86..f56801e 100644 --- a/Container.py +++ b/Container.py @@ -292,10 +292,9 @@ def generate_patch(world: "Rac2World", patch: Rac2ProcedurePatch, instruction=No # Set arg0 to 0x18 for ship shack patch.write_token(APTokenTypes.WRITE, address + 0x24, bytes([0x18, 0x00, 0x04, 0x24])) - # Allow first-person mode outside of NG+ if requested in options - if world.options.allow_first_person_mode: - for address in addresses.SPECIAL_MENU_FUNCS: - patch.write_token(APTokenTypes.WRITE, address + 0x1B0, NOP * 2) + # Allow first-person mode outside of NG+ + for address in addresses.SPECIAL_MENU_FUNCS: + patch.write_token(APTokenTypes.WRITE, address + 0x1B0, NOP * 2) # Enable bolt multiplier outside of NG+ if requested in options if world.options.enable_bolt_multiplier: diff --git a/Rac2Options.py b/Rac2Options.py index 6e58ccd..89e8515 100644 --- a/Rac2Options.py +++ b/Rac2Options.py @@ -47,11 +47,6 @@ class SkipWupashNebula(DefaultOnToggle): display_name = "Skip Wupash Nebula" -class AllowFirstPersonMode(DefaultOnToggle): - """Gives access to first person mode in 'Special' menu without being in New Game+.""" - display_name = "Allow First Person Mode" - - class EnableBoltMultiplier(Toggle): """Enables the bolt multiplier feature without being in New Game+.""" display_name = "Enable Bolt Multiplier" @@ -131,7 +126,6 @@ class Rac2Options(PerGameCommonOptions): randomize_gadgetron_vendor: RandomizeGadgetronVendor exclude_very_expensive_items: ExcludeVeryExpensiveItems skip_wupash_nebula: SkipWupashNebula - allow_first_person_mode: AllowFirstPersonMode enable_bolt_multiplier: EnableBoltMultiplier no_revisit_reward_change: NoRevisitRewardChange no_kill_reward_degradation: NoKillRewardDegradation diff --git a/Simplified Ratchet & Clank 2.yaml b/Simplified Ratchet & Clank 2.yaml index 74439f7..36ee431 100644 --- a/Simplified Ratchet & Clank 2.yaml +++ b/Simplified Ratchet & Clank 2.yaml @@ -61,9 +61,6 @@ Ratchet & Clank 2: # Skips the Wupash Nebula ship section that appears when first traveling to Maktar Nebula. skip_wupash_nebula: true - # Gives access to first person mode in 'Special' menu without being in New Game+. - allow_first_person_mode: true - # Enables the bolt multiplier feature without being in New Game+. enable_bolt_multiplier: false diff --git a/__init__.py b/__init__.py index d3ddad2..51a2362 100644 --- a/__init__.py +++ b/__init__.py @@ -147,8 +147,4 @@ def get_options_as_dict(self) -> Dict[str, Any]: ) def fill_slot_data(self) -> Mapping[str, Any]: - return self.get_options_as_dict() - - def generate_early(self): - if self.options.allow_first_person_mode_glitch_locations > 0: - assert self.options.allow_first_person_mode, "First Person Mode glitches enabled but not First Person Mode itself." \ No newline at end of file + return self.get_options_as_dict() \ No newline at end of file From de9d2175023c98ae12e8546448dcd17fb1e51f08 Mon Sep 17 00:00:00 2001 From: Pecomare Date: Thu, 27 Mar 2025 11:54:55 +0100 Subject: [PATCH 5/5] Rename option and adjust description --- Logic.py | 124 +++++++++++++++--------------- Rac2Options.py | 18 ++--- Simplified Ratchet & Clank 2.yaml | 14 ++-- 3 files changed, 78 insertions(+), 78 deletions(-) diff --git a/Logic.py b/Logic.py index d43b937..22a4531 100644 --- a/Logic.py +++ b/Logic.py @@ -86,7 +86,7 @@ def get_options(state: CollectionState, player: int) -> Rac2Options: def oozla_end_store_cutscene_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return can_dynamo(state, player) @@ -95,7 +95,7 @@ def oozla_end_store_cutscene_rule(state: CollectionState, player: int) -> bool: def oozla_tractor_puzzle_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return can_tractor(state, player) @@ -104,7 +104,7 @@ def oozla_tractor_puzzle_pb_rule(state: CollectionState, player: int) -> bool: def oozla_swamp_ruins_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return can_dynamo(state, player) @@ -118,7 +118,7 @@ def oozla_swamp_monster_ii_rule(state: CollectionState, player: int) -> bool: def maktar_photo_booth_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return (can_electrolyze(state, player) or can_heli(state, player)) @@ -149,7 +149,7 @@ def endako_crane_nt_rule(state: CollectionState, player: int) -> bool: def barlow_inventor_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return can_swingshot(state, player) @@ -158,7 +158,7 @@ def barlow_inventor_rule(state: CollectionState, player: int) -> bool: def barlow_overbike_race_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return can_electrolyze(state, player) return (can_improved_jump(state, player) @@ -172,7 +172,7 @@ def barlow_hound_cave_pb_rule(state: CollectionState, player: int) -> bool: def notak_top_pier_telescreen_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return (can_improved_jump(state, player) @@ -182,7 +182,7 @@ def notak_top_pier_telescreen_rule(state: CollectionState, player: int) -> bool: def notak_worker_bots_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return (can_heli(state, player) @@ -192,7 +192,7 @@ def notak_worker_bots_rule(state: CollectionState, player: int) -> bool: def notak_timed_dynamo_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return (can_dynamo(state, player) @@ -207,7 +207,7 @@ def siberius_defeat_thief_rule(state: CollectionState, player: int) -> bool: def siberius_flamebot_ledge_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return can_tractor(state, player) @@ -216,7 +216,7 @@ def siberius_flamebot_ledge_pb_rule(state: CollectionState, player: int) -> bool def siberius_fenced_area_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return can_heli(state, player) @@ -230,7 +230,7 @@ def tabora_meet_angelar_rule(state: CollectionState, player: int) -> bool: def tabora_underground_mines_end_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return (can_heli(state, player) and can_swingshot(state, player)) @@ -242,7 +242,7 @@ def tabora_underground_mines_end_rule(state: CollectionState, player: int) -> bo def tabora_canyon_glide_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return (can_heli(state, player) and can_swingshot(state, player) and can_glide(state, player)) @@ -261,7 +261,7 @@ def tabora_northeast_desert_pb_rule(state: CollectionState, player: int) -> bool def tabora_canyon_glide_pillar_nt_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return (can_heli(state, player) and can_swingshot(state, player) and can_glide(state, player)) @@ -275,7 +275,7 @@ def tabora_canyon_glide_pillar_nt_rule(state: CollectionState, player: int) -> b def dobbo_defeat_thug_leader_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return can_swingshot(state, player) return (can_swingshot(state, player) @@ -286,7 +286,7 @@ def dobbo_defeat_thug_leader_rule(state: CollectionState, player: int) -> bool: def dobbo_facility_terminal_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return (can_swingshot(state, player) @@ -298,7 +298,7 @@ def dobbo_facility_terminal_rule(state: CollectionState, player: int) -> bool: def dobbo_spiderbot_room_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return can_swingshot(state, player) return (can_swingshot(state, player) @@ -308,7 +308,7 @@ def dobbo_spiderbot_room_pb_rule(state: CollectionState, player: int) -> bool: def dobbo_facility_glide_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return (can_swingshot(state, player) @@ -319,7 +319,7 @@ def dobbo_facility_glide_pb_rule(state: CollectionState, player: int) -> bool: def dobbo_facility_glide_nt_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return (can_swingshot(state, player) @@ -334,7 +334,7 @@ def joba_hoverbike_race_rule(state: CollectionState, player: int) -> bool: def joba_shady_salesman_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return (can_dynamo(state, player) @@ -344,7 +344,7 @@ def joba_shady_salesman_rule(state: CollectionState, player: int) -> bool: def joba_arena_battle_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return can_levitate(state, player) return (can_dynamo(state, player) @@ -355,7 +355,7 @@ def joba_arena_battle_rule(state: CollectionState, player: int) -> bool: def joba_arena_cage_match_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return can_levitate(state, player) return (can_dynamo(state, player) @@ -366,7 +366,7 @@ def joba_arena_cage_match_rule(state: CollectionState, player: int) -> bool: def joba_hidden_cliff_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return (can_dynamo(state, player) @@ -376,7 +376,7 @@ def joba_hidden_cliff_pb_rule(state: CollectionState, player: int) -> bool: def joba_levitator_tower_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return can_levitate(state, player) return (can_dynamo(state, player) @@ -387,7 +387,7 @@ def joba_levitator_tower_pb_rule(state: CollectionState, player: int) -> bool: def joba_timed_dynamo_nt_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return can_dynamo(state, player) @@ -396,7 +396,7 @@ def joba_timed_dynamo_nt_rule(state: CollectionState, player: int) -> bool: def todano_search_rocket_silo_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return (can_electrolyze(state, player) @@ -407,10 +407,10 @@ def todano_search_rocket_silo_rule(state: CollectionState, player: int) -> bool: def todano_stuart_zurgo_trade_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_HARD: return has_qwark_statuette(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return (can_tractor(state, player) and has_qwark_statuette(state, player)) @@ -422,10 +422,10 @@ def todano_stuart_zurgo_trade_rule(state: CollectionState, player: int) -> bool: def todano_facility_interior_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_HARD: return True - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return can_tractor(state, player) return (can_electrolyze(state, player) @@ -435,10 +435,10 @@ def todano_facility_interior_rule(state: CollectionState, player: int) -> bool: def todano_near_stuart_zurgo_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_HARD: return True - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return can_tractor(state, player) return (can_electrolyze(state, player) @@ -448,7 +448,7 @@ def todano_near_stuart_zurgo_pb_rule(state: CollectionState, player: int) -> boo def todano_spiderbot_conveyor_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return (can_tractor(state, player) and can_improved_jump(state, player) and can_spiderbot(state, player)) @@ -462,7 +462,7 @@ def todano_spiderbot_conveyor_pb_rule(state: CollectionState, player: int) -> bo def todano_rocket_silo_nt_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return (can_electrolyze(state, player) @@ -472,14 +472,14 @@ def todano_rocket_silo_nt_rule(state: CollectionState, player: int) -> bool: def boldan_find_fizzwidget_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_HARD: return True - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return (can_gravity(state, player) and can_improved_jump(state, player)) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return (can_swingshot(state, player) and can_gravity(state, player)) @@ -491,7 +491,7 @@ def boldan_find_fizzwidget_rule(state: CollectionState, player: int) -> bool: def boldan_spiderbot_alley_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return (can_levitate(state, player) @@ -501,10 +501,10 @@ def boldan_spiderbot_alley_pb_rule(state: CollectionState, player: int) -> bool: def boldan_floating_platform_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return can_gravity(state, player) return (can_levitate(state, player) @@ -514,7 +514,7 @@ def boldan_floating_platform_rule(state: CollectionState, player: int) -> bool: def boldan_fountain_nt_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return can_levitate(state, player) @@ -523,10 +523,10 @@ def boldan_fountain_nt_rule(state: CollectionState, player: int) -> bool: def aranos_control_room_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_HARD: return True - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return (can_infiltrate(state, player) and can_levitate(state, player)) @@ -538,7 +538,7 @@ def aranos_control_room_rule(state: CollectionState, player: int) -> bool: def aranos_plumber_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return (can_gravity(state, player) @@ -548,7 +548,7 @@ def aranos_plumber_rule(state: CollectionState, player: int) -> bool: def aranos_under_ship_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return can_heli(state, player) return (can_gravity(state, player) @@ -558,7 +558,7 @@ def aranos_under_ship_pb_rule(state: CollectionState, player: int) -> bool: def aranos_omniwrench_12000_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return True return can_gravity(state, player) @@ -567,7 +567,7 @@ def aranos_omniwrench_12000_rule(state: CollectionState, player: int) -> bool: def snivelak_rescue_angelak_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >+ FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >+ FIRST_PERSON_EASY: return can_swingshot(state, player) return (can_swingshot(state, player) @@ -579,7 +579,7 @@ def snivelak_rescue_angelak_rule(state: CollectionState, player: int) -> bool: def snivelak_dynamo_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return can_swingshot(state, player) return (can_swingshot(state, player) @@ -592,7 +592,7 @@ def snivelak_dynamo_pb_rule(state: CollectionState, player: int) -> bool: def snivelak_swingshot_tower_nt_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return can_swingshot(state, player) return (can_swingshot(state, player) @@ -602,7 +602,7 @@ def snivelak_swingshot_tower_nt_rule(state: CollectionState, player: int) -> boo def smolg_balloon_transmission_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return can_electrolyze(state, player) return (can_improved_jump(state, player) @@ -613,7 +613,7 @@ def smolg_balloon_transmission_rule(state: CollectionState, player: int) -> bool def smolg_distribution_facility_end_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return can_electrolyze(state, player) return (can_improved_jump(state, player) @@ -626,7 +626,7 @@ def smolg_distribution_facility_end_rule(state: CollectionState, player: int) -> def smolg_mutant_crab_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: if not can_levitate(state, player): return False return (can_swingshot(state, player) @@ -639,7 +639,7 @@ def smolg_mutant_crab_rule(state: CollectionState, player: int) -> bool: def smolg_floating_platform_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: if not can_levitate(state, player): return False return (can_swingshot(state, player) @@ -652,7 +652,7 @@ def smolg_floating_platform_pb_rule(state: CollectionState, player: int) -> bool def smolg_warehouse_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return (can_dynamo(state, player) @@ -686,7 +686,7 @@ def damosel_pyramid_pb_rule(state: CollectionState, player: int) -> bool: def grelbin_find_angela_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return can_hypnotize(state, player) @@ -715,15 +715,15 @@ def grelbin_yeti_cave_pb_rule(state: CollectionState, player: int) -> bool: def yeedil_defeat_mutated_protopet_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_HARD: return can_infiltrate(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return (can_hypnotize(state, player) and can_swingshot(state, player) and can_infiltrate(state, player)) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return (can_hypnotize(state, player) and can_swingshot(state, player) and can_infiltrate(state, player) @@ -741,7 +741,7 @@ def yeedil_defeat_mutated_protopet_rule(state: CollectionState, player: int) -> def yeedil_bridge_grindrail_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return True return can_grind(state, player) @@ -750,15 +750,15 @@ def yeedil_bridge_grindrail_pb_rule(state: CollectionState, player: int) -> bool def yeedil_tractor_pillar_pb_rule(state: CollectionState, player: int) -> bool: options = get_options(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_HARD: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_HARD: return can_infiltrate(state, player) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_MEDIUM: return (can_hypnotize(state, player) and can_swingshot(state, player) and can_infiltrate(state, player)) - if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: + if options.first_person_mode_glitch_in_logic >= FIRST_PERSON_EASY: return (can_hypnotize(state, player) and can_swingshot(state, player) and can_infiltrate(state, player) diff --git a/Rac2Options.py b/Rac2Options.py index 89e8515..ea21e4b 100644 --- a/Rac2Options.py +++ b/Rac2Options.py @@ -103,14 +103,14 @@ class ExtendWeaponProgression(Toggle): display_name = "Extended Weapon Progression" -class AllowFirstPersonModeGlitchLocations(Choice): - """Allows the logic to use checks reachable with 1st person mode glitch. - The setting relates to the difficulty of performing the glitch. For exmaple: - Easy: Getting the Platinum Bolt near the Tractor Beam exchange in Oozla. - Medium: Getting to the Notak Worker Bots without the Heli-pack nor the Thermanator. - Hard: Getting to the Mutated Protopet without the Hypnomatic.""" - display_name = "Allow 1st Person Mode Glitch" - option_no = 0 +class FirstPersonModeGlitchInLogic(Choice): + """Determines if logic should take first person mode glitches into account when evaluating which locations are + reachable. Various difficulty levels can be picked: + - Easy: simple climbs (e.g. getting the Platinum Bolt near Oozla scientist) + - Medium: harder climbs and basic lateral movement (e.g. Getting to the Notak Worker Bots without the Heli-pack nor the Thermanator) + - Hard: full navigation following walls (e.g. Getting to the Mutated Protopet only with the Infiltrator)""" + display_name = "First Person Mode Glitch In Logic" + option_disabled = 0 option_easy = 1 option_medium = 2 option_hard = 3 @@ -134,4 +134,4 @@ class Rac2Options(PerGameCommonOptions): weapon_xp_multiplier: WeaponExperienceMultiplier extra_spaceship_challenge_locations: ExtraSpaceshipChallengeLocations extend_weapon_progression: ExtendWeaponProgression - allow_first_person_mode_glitch_locations: AllowFirstPersonModeGlitchLocations + first_person_mode_glitch_in_logic: FirstPersonModeGlitchInLogic diff --git a/Simplified Ratchet & Clank 2.yaml b/Simplified Ratchet & Clank 2.yaml index 36ee431..e9e2149 100644 --- a/Simplified Ratchet & Clank 2.yaml +++ b/Simplified Ratchet & Clank 2.yaml @@ -101,13 +101,13 @@ Ratchet & Clank 2: # This effectively makes all weapons that are usually restricted to NG+ available with enough grinding. extend_weapon_progression: false - # Allows the logic to use checks reachable with 1st person mode glitch - # Values are: no, easy, medium and hard - # The setting relates to the difficulty of performing the glitch. For exmaple: - # Easy: Getting the Platinum Bolt near the Tractor Beam exchange in Oozla. - # Medium: Getting to the Notak Worker Bots without the Heli-pack nor the Thermanator. - # Hard: Getting to the Mutated Protopet without the Hypnomatic. - allow_first_person_mode_glitch_locations: no + # Determines if logic should take first person mode glitches into account when evaluating which locations are reachable. + # Various difficulty levels can be picked: + # - Easy: simple climbs (e.g. getting the Platinum Bolt near Oozla scientist) + # - Medium: harder climbs and basic lateral movement (e.g. Getting to the Notak Worker Bots without the Heli-pack nor the Thermanator) + # - Hard: full navigation following walls (e.g. Getting to the Mutated Protopet only with the Infiltrator) + # Can be disabled with value disabled. + first_person_mode_glitch_in_logic: no # Item & Location Options local_items: