diff --git a/locations.py b/locations.py index 628bf51..fe5c5e5 100644 --- a/locations.py +++ b/locations.py @@ -101,7 +101,7 @@ class MZMLocation(Location): tourian_location_table = { "Tourian Left of Mother Brain": AP_MZM_ID_BASE + 73, - "Tourian Under Mother Brain ": AP_MZM_ID_BASE + 74, + "Tourian Under Mother Brain": AP_MZM_ID_BASE + 74, "Mother Brain": None } diff --git a/logic.py b/logic.py index b28d2da..974e661 100644 --- a/logic.py +++ b/logic.py @@ -107,7 +107,9 @@ def can_tricky_sparks(state: CollectionState, player: int) -> bool: def brinstar_past_hives(state: CollectionState, player: int) -> bool: - return state.has("Morph Ball", player) and has_missile_count(state, player, 10) + return (state.has("Morph Ball", player) + and (has_missile_count(state, player, 10) + or state.has_any({"Long Beam", "Ice Beam", "Wave Beam", "Plasma Beam"}, player))) # used for the items in this area as well as determining whether the ziplines can be activated @@ -210,7 +212,8 @@ def ridley_left_shaft_access(state: CollectionState, player: int) -> bool: return (has_super_missiles(state, player) and (can_hj_sj_ibj_or_grip(state, player) or can_walljump(state, player) or state.has("Ice Beam", player) or can_bomb_block(state, player)) - and (can_traverse_heat(state, player) or hellrun(state, player, 1)) + and (can_traverse_heat(state, player) or hellrun(state, player, 1) + or (can_space_jump(state, player) and can_bomb_block(state, player))) ) @@ -240,11 +243,11 @@ def ridley_central_access(state: CollectionState, player: int) -> bool: ) -# ice beam makes dealing with the pirates a ton easier. etanks keeps you from needing to go too deep before you have +# ice/plasma beam makes dealing with the pirates a ton easier. etanks keeps you from needing to go too deep before you have # a decent chance to survive. the rest is the strictest requirement to get in and back out of the chozo ghost area def chozodia_ghost_from_upper_crateria_door(state: CollectionState, player: int) -> bool: return ( - state.has("Ice Beam", player) and (state.count("Energy Tank", player) >= 4) + state.has_any({"Ice Beam", "Plasma Beam"}, player) and (state.count("Energy Tank", player) >= 4) and has_missiles(state, player) and (can_walljump(state, player) or can_ibj(state, player) or can_space_jump(state, player)) diff --git a/regions.py b/regions.py index 1a9cd9f..49cbe75 100644 --- a/regions.py +++ b/regions.py @@ -5,9 +5,11 @@ ridley_location_table, tourian_location_table, crateria_location_table, chozodia_location_table, MZMLocation) from . import logic + if TYPE_CHECKING: from . import MZMWorld + # TODO: Split regions up into sub-regions based on shared-access logic rules def create_regions(world: MZMWorld): @@ -48,8 +50,6 @@ def create_regions(world: MZMWorld): menu.connect(brinstar) - # TODO: finish logic - brinstar.connect(norfair, "Brinstar-Norfair elevator", lambda state: logic.can_bomb_block(state, world.player)) @@ -66,27 +66,22 @@ def create_regions(world: MZMWorld): and state.has("Speed Booster", world.player) )) - brinstar.connect(tourian, "Brinstar-Tourian elevator", lambda state: - state.has_all({"Kraid Defeated", "Ridley Defeated"}, world.player)) + brinstar.connect(tourian, "Brinstar-Tourian elevator", + lambda state: state.has_all({"Kraid Defeated", "Ridley Defeated"}, world.player)) norfair.connect(crateria, "Norfair-Crateria elevator", lambda state: logic.can_long_beam(state, world.player)) norfair.connect(ridley, "Norfair-Ridley elevator", lambda state: ( - ((logic.norfair_to_save_behind_hijump(state, world.player) - and logic.has_missile_count(state, world.player, 4) - and state.has_all({"Wave Beam", "Speed Booster"}, world.player) - ) - or logic.norfair_shortcut(state, world.player)) - and (logic.has_missile_count(state, world.player, 6) - or logic.has_power_bombs(state, world.player)) + ((logic.norfair_to_save_behind_hijump(state, world.player) + and logic.has_missile_count(state, world.player, 4) + and state.has_all({"Wave Beam", "Speed Booster"}, world.player) + ) + or logic.norfair_shortcut(state, world.player)) + and (logic.has_missile_count(state, world.player, 6) + or logic.has_power_bombs(state, world.player)) )) - #tourian.connect(crateria, "Tourian-Crateria Elevator") - # there's a door lock on the crateria side if you haven't killed Mother Brain - # in rando. in vanilla it's got a super missile door, weirdly. but the elevator simply - # doesn't work until after escape i guess. i don't think this is necessary in any case - crateria.connect(chozodia, "Crateria-Chozodia Upper Door", lambda state: ( logic.has_power_bombs(state, world.player) and (logic.can_ibj(state, world.player) @@ -95,5 +90,5 @@ def create_regions(world: MZMWorld): and (state.has("Mother Brain Defeated", world.player) or not world.options.chozodia_access.value))) crateria.connect(chozodia, "Crateria-Chozodia Lower Door", lambda state: ( - logic.has_power_bombs(state, world.player) - and (state.has("Mother Brain Defeated", world.player) or not world.options.chozodia_access.value))) + logic.has_power_bombs(state, world.player) + and (state.has("Mother Brain Defeated", world.player) or not world.options.chozodia_access.value))) diff --git a/rules.py b/rules.py index f35e03f..ea292f5 100644 --- a/rules.py +++ b/rules.py @@ -8,6 +8,7 @@ from typing import TYPE_CHECKING from worlds.generic.Rules import add_rule from . import logic + if TYPE_CHECKING: from . import MZMWorld @@ -87,8 +88,16 @@ def set_rules(world: MZMWorld, locations): lambda state: (logic.has_missiles(state, player) and logic.can_bomb_block(state, player)), "Brinstar Post-Hive Missile": lambda state: logic.brinstar_past_hives(state, player), - "Brinstar Upper Pillar Missile": lambda state: (logic.can_bomb_block(state, player) - and state.has_any({"Bomb", "Hi-Jump"}, player)), + "Brinstar Upper Pillar Missile": + lambda state: ((logic.can_bomb_block(state, player) and state.has_any({"Bomb", "Hi-Jump"}, player)) + or (logic.brinstar_past_hives(state, player) + and (logic.can_ibj(state, player) + or (logic.can_space_jump(state, player) + and state.has_any({"Bomb", "Hi-Jump"}, player)) + or (logic.can_walljump(state, player) + and state.has_all({"Hi-Jump", "Ice Beam"}, player))) + ) + ), "Brinstar Behind Bombs": lambda state: (logic.brinstar_past_hives(state, player) and (logic.can_bomb_block(state, player) @@ -318,7 +327,7 @@ def set_rules(world: MZMWorld, locations): or state.has_all({"Long Beam", "Wave Beam"}, player)) and (logic.has_missile_count(state, player, 5) and (logic.can_walljump(state, player) or logic.can_space_jump(state, player) - or logic.can_space_jump(state, player) or state.has("Power Grip", player))) + or state.has("Power Grip", player))) ), "Ridley Southwest Puzzle Bottom": lambda state: ( (logic.ridley_longway_right_shaft_access(state, player) @@ -382,7 +391,7 @@ def set_rules(world: MZMWorld, locations): or (state.has("Power Grip", player) and logic.has_power_bombs(state, player) and state.has_any({"Ice Beam", "Hi-Jump"}, player))) and (logic.can_bomb_block(state, player) or state.has("Screw Attack", player)) - ), # can also do this without ice beam using hj, grip, and walljumps + ), # can also do this without ice beam using hj, grip, and walljumps "Ridley Bomb Puzzle": lambda state: ( (logic.ridley_longway_right_shaft_access(state, player) or logic.ridley_shortcut_right_shaft_access(state, player)) @@ -439,7 +448,8 @@ def set_rules(world: MZMWorld, locations): chozodia_access_rules = { "Chozodia Upper Crateria Door": lambda state: ( - logic.has_missiles(state, player) + state.can_reach_entrance("Crateria-Chozodia Upper Door", player) + and logic.has_missiles(state, player) and (logic.can_walljump(state, player) or logic.can_ibj(state, player) or logic.can_space_jump(state, player)) ), @@ -460,7 +470,8 @@ def set_rules(world: MZMWorld, locations): or (state.has("Hi-Jump", player) and state.has_any({"Speed Booster", "Power Grip"}, player))) ), "Chozodia Ruins Near Upper Crateria Door": lambda state: ( - logic.has_missiles(state, player) + state.can_reach_entrance("Crateria-Chozodia Upper Door", player) + and logic.has_missiles(state, player) and (logic.can_walljump(state, player) or logic.can_ibj(state, player) or logic.can_space_jump(state, player)) and state.has("Power Bomb Tank", player) @@ -523,7 +534,7 @@ def set_rules(world: MZMWorld, locations): ), "Chozodia Mothership Ceiling Near ZSS Start": lambda state: logic.chozodia_tube_to_mothership_central(state, player) - or state.has_all({"Chozo Ghost Defeated", "Power Bomb"}, player), + or state.has_all({"Chozo Ghost Defeated", "Power Bomb Tank"}, player), "Chozodia Under Mecha Ridley Hallway": lambda state: ( # you can also get here without PBs but we'll save that for advanced logic later logic.chozodia_to_cockpit(state, player) @@ -532,8 +543,10 @@ def set_rules(world: MZMWorld, locations): ), "Chozodia Southeast Corner In Hull": lambda state: logic.chozodia_tube_to_mothership_central(state, player) - or state.has_all({"Chozo Ghost Defeated", "Power Bomb"}, player), - "Chozo Ghost": lambda state: state.has("Mother Brain Defeated", player), + or state.has_all({"Chozo Ghost Defeated", "Power Bomb Tank"}, player), + "Chozo Ghost": lambda state: ( + state.has("Mother Brain Defeated", player) + and (state.has("Power Grip", player) or logic.can_ibj(state, player))), # Grip/IBJ needed to escape "Mecha Ridley": lambda state: ( logic.chozodia_to_cockpit(state, player) and logic.has_missile_count(state, player, 40)