Files
Jonathan Tinney 7971961166
Some checks failed
Analyze modified files / flake8 (push) Failing after 2m28s
Build / build-win (push) Has been cancelled
Build / build-ubuntu2204 (push) Has been cancelled
ctest / Test C++ ubuntu-latest (push) Has been cancelled
ctest / Test C++ windows-latest (push) Has been cancelled
Analyze modified files / mypy (push) Has been cancelled
Build and Publish Docker Images / Push Docker image to Docker Hub (push) Successful in 5m4s
Native Code Static Analysis / scan-build (push) Failing after 5m2s
type check / pyright (push) Successful in 1m7s
unittests / Test Python 3.11.2 ubuntu-latest (push) Failing after 16m23s
unittests / Test Python 3.12 ubuntu-latest (push) Failing after 28m19s
unittests / Test Python 3.13 ubuntu-latest (push) Failing after 14m49s
unittests / Test hosting with 3.13 on ubuntu-latest (push) Successful in 5m0s
unittests / Test Python 3.13 macos-latest (push) Has been cancelled
unittests / Test Python 3.11 windows-latest (push) Has been cancelled
unittests / Test Python 3.13 windows-latest (push) Has been cancelled
add schedule I, sonic 1/frontiers/heroes, spirit island
2026-04-02 23:46:36 -07:00

2344 lines
63 KiB
Python

"""
Logic rule definitions for Metroid: Zero Mission.
Logic based on MZM Randomizer, by Biospark and dragonfangs.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from .logic import *
from .tricks import Trick
from worlds.generic.Rules import add_rule
if TYPE_CHECKING:
from . import MZMWorld
def set_location_rules(world: MZMWorld, locations):
brinstar_start = {
"Brinstar Morph Ball": None,
"Brinstar Morph Ball Cannon": CanBallCannon,
"Brinstar Ceiling E-Tank": any(
all(
IceBeam,
any(
RidleyBoss,
HardMode
)
),
CanFly,
Trick("Brinstar Ceiling E-Tank Tricky Spark")
),
}
brinstar_main = {
"Brinstar Long Beam": all(
MorphBall,
any(
CanLongBeam(2),
LayoutPatches("brinstar_long_beam_hall"),
)
),
"Brinstar Main Shaft Left Alcove": all(
CanSingleBombBlock,
any(
CanFlyWall,
IceBeam,
CanHiGrip
)
),
"Brinstar Ballspark": all(
CanBallspark,
CanBombTunnelBlock
),
"Brinstar Ripper Climb": any(
all(
PowerGrip,
any(
all(
IceBeam,
NormalMode # On Hard, one Ripper is missing
),
CanFlyWall
),
any(
CanBallJump,
CanSingleBombBlock,
LayoutPatches("brinstar_top")
)
),
CanIBJ,
Trick("Brinstar Ripper Climb Zoomer Freeze"),
Trick("Brinstar Ripper Climb Tricky Spark")
),
"Brinstar Speed Booster Shortcut": all(
any(
CanBallspark,
all( # Reverse way
NormalLogic,
CanBallJump
),
),
CanBombTunnelBlock,
CanVerticalWall,
),
"Brinstar Worm Drop": all(
MorphBall,
Missiles
),
"Brinstar First Missile": MorphBall,
"Brinstar Behind Hive": all(
MorphBall,
Missiles
),
"Brinstar Under Bridge": all(
Missiles,
CanSingleBombBlock
),
}
brinstar_top = {
"Brinstar Upper Pillar": None
}
brinstar_varia_area = {
"Brinstar Varia Suit": all(
any(
CanHorizontalIBJ,
PowerGrip,
all(
GravitySuit,
CanVerticalWall
),
all(
any(
HazardRuns, # only 99 energy required as you can refill at the Chozo statue
VariaSuit
),
CanHiWallJump,
any( # The walljump up out of the acid is a little tight but doesn't feel worthy of a trick
SpaceJump,
NormalLogic
)
),
),
any(
Bomb,
Trick("Brinstar Varia Suit Power Bomb")
),
CanEnterMediumMorphTunnel,
Missiles
),
"Brinstar Acid Near Varia": all(
any(
CanLongBeam(5),
WaveBeam
),
any(
VariaSuit,
GravitySuit,
Trick("Brinstar Acid Near Varia Acid Dive - Normal"),
Trick("Brinstar Acid Near Varia Acid Dive - Minimal")
)
),
}
brinstar_pasthives = {
"Brinstar Post-Hive in Wall": None,
"Brinstar Behind Bombs": all(
Missiles,
CanBombTunnelBlock,
CanBallJump
),
"Brinstar Bomb": Missiles,
"Brinstar Post-Hive Pillar": None
}
kraid_main = {
"Kraid Save Room Tunnel": CanBombTunnelBlock,
"Kraid Zipline Morph Jump": any(
all(
Ziplines,
CanBallJump
),
Trick("Kraid Zipline Morph Jump Without Ziplines")
),
"Kraid Acid Ballspark": all(
any(
CanIBJ, # Gravity is required for this item so regular IBJ works, unlike regional access
PowerGrip,
all( # A bit of a tight jump and kind of unintuitive
CanHiSpringBall,
NormalLogic
)
),
CanBombTunnelBlock,
GravitySuit,
CanBallspark
),
"Kraid Right Hall Pillar": Missiles,
"Kraid Speed Jump": all(
Missiles,
SpeedBooster
),
"Kraid Upper Right Morph Ball Cannon": all(
Missiles,
CanBallCannon
)
}
kraid_acidworm_area = {
"Kraid Under Acid Worm": all(
Missiles,
any(
NormalCombat,
all(
MissileTanks(5),
EnergyTanks(1)
)
),
CanSingleBombBlock,
CanVerticalWall
),
"Kraid Zipline Activator Room": None,
"Kraid Zipline Activator": None
}
# past the long acid pool
kraid_left_shaft = {
"Kraid Behind Giant Hoppers": CanEnterHighMorphTunnel,
"Kraid Quad Ball Cannon Room": any(
all(
CanBombTunnelBlock,
Ziplines,
Missiles
),
Trick("Kraid Quad Ball Cannon No Bombs"),
Trick("Kraid Quad Ball Cannon Crumble Grip Hi-Jump"),
Trick("Kraid Quad Ball Cannon Crumble Grip Space Jump")
),
"Kraid Unknown Item Statue": all(
any(
Bomb,
PowerBombCount(4), # nowhere good to refill PBs between elevator shaft and here
ScrewAttack,
Trick("Kraid Unknown Item Spaceboost"), # 3 PBs
Trick("Kraid Unknown Item With 2 PBs"), # 2 PBs
),
any( # To enter the morph tunnel to leave after getting the item on the statue
PowerGrip,
CanHiSpringBall,
CanIBJ,
all(
IceBeam,
CanBallJump
)
)
)
}
kraid_bottom = {
"Kraid Speed Booster": any(
KraidBoss,
all(
NormalLogic,
SpeedBooster
)
),
"Kraid Acid Fall": None,
"Kraid": all(
any(
UnknownItem2,
all(
NormalLogic,
SpeedBooster
)
),
Missiles,
KraidCombat,
any( # to escape, or to get to the upper door if you take the speed booster exit into the room
SpeedBooster,
CanHiGrip,
CanFlyWall
),
any( # to escape via the bottom right shaft
LayoutPatches("kraid_right_shaft"),
SpeedBooster,
CanFly,
Trick("Kraid Bottom Escape Enemy Freeze"),
Trick("Kraid Bottom Escape Get-Around Walljump")
)
)
}
norfair_main = {
"Norfair Hallway to Crateria": any(
PowerGrip,
CanIBJ,
all(
IceBeam,
CanEnterMediumMorphTunnel
)
),
"Norfair Under Crateria Elevator": all(
any(
CanLongBeam(1),
CanBallspark
),
any(
CanEnterHighMorphTunnel,
Trick("Norfair Under Crateria Elevator Enemy Freeze")
)
)
}
norfair_right_shaft = {
"Norfair Big Room": any(
SpeedBooster,
CanFly,
all(
IceBeam,
CanVerticalWall
),
Trick("Norfair Big Room Walljump")
)
}
norfair_upper_right = {
"Norfair Ice Beam": all(
any(
SpaceJump,
CanHorizontalIBJ,
PowerGrip,
all(
HazardRuns,
CanWallJump
),
all(
IceBeam,
HardMode
),
Trick("Norfair Ice Beam Hi-Jump Only")
),
any( # Escape
SuperMissiles,
all(
any(
CanLongBeam(2),
WaveBeam
),
any(
IceBeam,
CanFlyWall,
CanHiGrip
)
)
)
),
"Norfair Heated Room Above Ice Beam": any(
VariaSuit,
Trick("Norfair Above Ice Hellrun - Normal"),
Trick("Norfair Above Ice Hellrun - Minimal"),
)
}
norfair_behind_ice = {
"Norfair Behind Top Chozo Statue": None, # TODO Hard has extra considerations
}
norfair_under_brinstar_elevator = {
"Norfair Bomb Trap": all(
CanReachLocation("Norfair Heated Room Under Brinstar Elevator"),
any(
Bomb,
Trick("Norfair Bomb Trap PB Only"),
all(
PowerBombs,
SpaceJump
)
)
),
"Norfair Heated Room Under Brinstar Elevator": all(
SuperMissiles,
any(
VariaSuit,
Trick("Norfair Under Elevator Hellrun - Normal"),
Trick("Norfair Under Elevator Hellrun - Minimal")
)
),
}
norfair_lowerrightshaft = {
"Norfair Hi-Jump": Missiles,
}
norfair_lowerrightshaft_by_hijump = {
"Norfair Right Shaft Near Hi-Jump": None
}
lower_norfair = {
"Norfair Lava Dive Left": all(
MissileCount(7),
GravitySuit,
CanFly
),
"Norfair Lava Dive Right": all(
MissileCount(5),
any(
GravitySuit,
Trick("Lower Norfair Lava Dive - Normal"),
Trick("Lower Norfair Lava Dive - Minimal")
),
any(
CanBombTunnelBlock,
WaveBeam
),
any(
all(
GravitySuit,
CanVerticalWall
),
PowerGrip,
CanHiWallJump
)
),
"Norfair Wave Beam": MissileCount(4),
"Norfair Heated Room Below Wave - Left": all(
CanVerticalWall,
any(
VariaSuit,
Trick("Norfair Under Wave Hellrun Left - Normal"),
Trick("Norfair Under Wave Hellrun Left - Minimal")
),
any(
CanIBJ,
CanHiSpringBall,
PowerGrip,
all(
IceBeam,
CanBallJump
)
)
),
"Norfair Heated Room Below Wave - Right": all(
CanVerticalWall,
any(
VariaSuit,
Trick("Norfair Under Wave Hellrun Right - Normal"),
Trick("Norfair Under Wave Hellrun Right - Minimal")
)
),
}
norfair_screwattack = {
"Norfair Screw Attack": None,
"Norfair Next to Screw Attack": ScrewAttack,
}
norfair_behind_superdoor = {
"Norfair Behind Lower Super Missile Door - Left": all(
any(
all(
CanIBJ,
GravitySuit,
),
all(
SpaceJump,
PowerGrip
),
all( # This is a kinda tight and unintuitive walljump but doesn't feel trick-worthy
NormalLogic,
GravitySuit,
CanHiGrip,
CanWallJump
),
Trick("Norfair Behind Lower Super Missile Door - Left Enemy Freeze"),
Trick("Norfair Behind Lower Super Missile Door - Left Damage Boost"),
Trick("Rising Midair Morph With Space Jump"),
all(
HazardRuns,
Trick("Balljump to IBJ From Acid"),
)
),
any( # To get out
LayoutPatches("norfair_behind_superdoor"),
SpeedBooster,
CanBallJump
)
),
"Norfair Behind Lower Super Missile Door - Right": any(
SpaceJump,
CanHorizontalIBJ,
all(
CanIBJ,
GravitySuit
),
all(
IceBeam,
CanWallJump
),
all(
HiJump,
IceBeam,
),
all(
GravitySuit,
CanHiWallJump
),
all(
HazardRuns,
Trick("Balljump to IBJ From Acid")
)
)
}
norfair_bottom = {
"Norfair Larva Ceiling": CanReachEntrance("Lower Norfair -> Bottom"),
"Norfair Right Shaft Bottom": any(
# going from the right "stairs"
all(
any(
CanVerticalWall,
IceBeam
),
CanBallJump
),
# using the shot blocks to the left
all(
NormalLogic,
Missiles,
PowerGrip,
any(
CanFlyWall,
IceBeam
)
)
)
}
ridley_main = {
"Ridley Imago Super Missile": all(
CanVerticalWall,
any(
all(
MissileTanks(7),
EnergyTanks(1)
),
all(
NormalCombat,
MissileTanks(4),
),
all(
MinimalCombat,
any(
MissileTanks(1),
SuperMissileCount(8)
)
),
ChargeBeam
)
)
}
ridley_left_shaft = {
"Ridley West Pillar": None,
"Ridley Fake Floor": any(
CanBombTunnelBlock, # the long way
CanFly, # the short way
Trick("Ridley Fake Floor Skip") # the short way but spicy
),
}
ridley_sw_puzzle = {
"Ridley Southwest Puzzle Top": all(
CanReachLocation("Ridley Southwest Puzzle Bottom"),
MissileCount(5),
any(
CanWallJump,
PowerGrip,
SpaceJump
)
),
"Ridley Southwest Puzzle Bottom": all(
SpeedBooster,
MorphBall,
any(
CanIBJ,
all(
PowerGrip,
any(
HiJump,
SpaceJump,
CanWallJump
)
)
),
Missiles,
any(
PowerGrip,
Trick("Ridley Southwest Puzzle Crumble Jump")
),
any(
PowerGrip,
PowerBombs,
all(
LongBeam,
WaveBeam
)
)
)
}
ridley_right_shaft = {
"Ridley Long Hall": None,
"Ridley Northeast Corner": any(
CanFly,
all(
IceBeam,
any(
CanWallJump,
CanHiGrip
)
),
Trick("Ridley Northeast Corner Get-Around Walljump"),
)
}
ridley_right_speed_puzzles = {
"Ridley Bomb Puzzle": all(
any(
PowerGrip,
Trick("Ridley Bomb Puzzle No Grip")
),
any(
all(
Bomb,
any(
CanWallJump,
SpaceJump
)
),
Trick("Ridley Bomb Puzzle Power Bombs")
)
),
"Ridley Speed Jump": all(
Missiles,
any(
WaveBeam,
Trick("Ridley Speed Jump No Wave")
)
)
}
ridley_central = {
"Ridley Upper Ball Cannon Puzzle": all(
any(
CanIBJ,
all(
PowerGrip,
any(
CanWallJump,
SpaceJump,
PowerBombs,
NormalLogic
)
),
all(
CanHiSpringBall,
NormalLogic
)
),
any(
CanBallCannon,
LayoutPatches("ridley_ballcannon")
)
),
"Ridley Lower Ball Cannon Puzzle": all(
any(
PowerBombs,
PowerGrip,
all(
WaveBeam,
any(
CanWallJump,
SpaceJump
)
)
),
any(
CanBallCannon,
all(
LayoutPatches("ridley_ballcannon"),
any(
HiJump,
SpaceJump,
PowerGrip,
CanWallJump
)
)
)
),
"Ridley After Sidehopper Hall Upper": None,
"Ridley After Sidehopper Hall Lower": None,
"Ridley Center Pillar": any(
CanWallJump,
PowerGrip,
IceBeam,
SpaceJump,
CanHorizontalIBJ,
all(
NormalLogic,
HiJump
)
),
"Ridley Ball Room Lower": None,
"Ridley Ball Room Upper": all(
SuperMissiles,
any(
CanFlyWall,
CanHiGrip
),
any(
Bomb,
PowerBombCount(3)
)
),
"Ridley Fake Lava Under Floor": all(
any(
WaveBeam,
CanBombTunnelBlock
),
CanEnterHighMorphTunnel
),
"Ridley Under Owls": None,
}
ridley_room = {
"Ridley Behind Unknown Statue": UnknownItem3,
"Ridley Unknown Item Statue": None,
"Ridley": UnknownItem3,
}
tourian = {
"Tourian Left of Mother Brain": all(
ChozoGhostBoss,
MotherBrainBoss,
SpeedBooster,
any(
SpaceJump,
NormalLogic
)
),
"Tourian Under Mother Brain": all(
ChozoGhostBoss,
MotherBrainBoss,
SuperMissiles,
CanEnterMediumMorphTunnel # to escape
),
"Mother Brain": all(
IceBeam,
any(
Bomb, # only bomb can unlatch metroids
NormalCombat # or just don't get hit!
),
MotherBrainCombat,
any( # to get through the tunnel right before Mother Brain
CanEnterHighMorphTunnel,
Trick("Mother Brain Access Wall Jump"),
Trick("Mother Brain Access Ice Only")
),
any( # to get through escape shaft
all(
NormalMode,
CanVertical,
),
any( # Hard mode escape; much tighter time so rules are different
SpaceJump,
HiJump,
all(
PowerGrip,
CanWallJump
),
Trick("Tourian Escape Hard Mode IBJ")
),
Trick("Tourian Escape Shinespark")
),
any( # to get to ship
SpeedBooster,
CanFly,
all(
NormalLogic,
CanHiWallJump
)
)
)
}
crateria_main = {
"Crateria Landing Site Ballspark": all(
CanBallspark,
PowerBombs,
any(
GravitySuit,
CanReachEntrance("Crateria Left -> Landing Site")
)
),
"Crateria Moat": None,
"Crateria Statue Water": UnknownItem1,
"Crateria Unknown Item Statue": all(
any(
CanVertical,
CanBombTunnelBlock
),
CanBallJump
),
}
crateria_upper_right = {
"Crateria East Ballspark": all(
CanBallspark,
any(
CanReachEntrance("Crateria -> Chozodia Upper Door"),
CanReachLocation("Crateria Northeast Corner")
)
),
"Crateria Northeast Corner": all(
SpeedBooster,
any(
SpaceJump,
CanWallJump,
Trick("Crateria Northeast Corner Tricky Spark")
)
)
}
crateria_powergrip = {
"Crateria Power Grip": None
}
chozodia_ruins_crateria_entrance = {
"Chozodia Upper Crateria Door":
CanReachEntrance("Crateria -> Chozodia Upper Door"), # Specifically need to access this entrance, not just the region as it's one-way
"Chozodia Ruins East of Upper Crateria Door": Missiles,
"Chozodia Triple Crawling Pirates": all(
Missiles,
PowerBombCount(2), # 2 PBs ALWAYS required at minimum, but you may need many more
any(
all(
Bomb,
any(
NormalMode,
PowerBombCount(3) # on Hard a save room is disabled, so you cannot refill PBs, requiring more
)
),
PowerBombCount(7), # Hard, no refills, only PBs, no ability to skip any bomb chains
all(
NormalMode,
PowerBombCount(5), # no skipping bomb reqs, but with refills
),
all( # Skips one PB on either the slow-crumble morph tunnel or the bomb chain after
any(
PowerBombCount(6),
all(
NormalMode,
PowerBombCount(4)
)
),
any(
ScrewAttack,
WaveBeam,
CanFlyWall
),
NormalLogic
),
all( # Skips both but still only PBs
any(
ScrewAttack,
WaveBeam
),
CanFlyWall,
any(
PowerBombCount(5),
all(
NormalMode,
PowerBombCount(3)
)
)
),
),
any(
CanHiGrip,
CanFlyWall,
Trick("Chozodia Pirates Enemy Freezes"),
),
ChozodiaCombat
)
}
chozodia_ruins_test = {
"Chozodia Chozo Ghost Area Morph Tunnel Above Water": all(
MissileCount(3),
CanBallJump,
any(
all( # Going up through the water
any(
CanWallJump,
all(
GravitySuit,
CanFly
),
),
any(
ScrewAttack,
NormalLogic # Skipping the screw attack wall with the missile tunnel
)
),
CanFlyWall, # Access up through the long shaft
)
),
"Chozodia Chozo Ghost Area Underwater": all(
Missiles,
SpeedBooster,
GravitySuit
),
"Chozodia Chozo Ghost Area Long Shinespark": all(
Missiles,
SpeedBooster,
GravitySuit,
any( # IBJ is too slow to keep charge
SpaceJump,
CanWallJump
),
any(
ScrewAttack,
Trick("Chozo Ghost Shinespark No Screw")
)
),
"Chozodia Lava Dive": all(
any(
ScrewAttack,
all(
Missiles,
any(
Bomb,
PowerBombCount(2)
)
)
),
any(
all(
GravitySuit,
CanEnterHighMorphTunnel,
CanBallJump
),
Trick("Chozodia Lava Dive Item - Normal"),
Trick("Chozodia Lava Dive Item - Minimal"),
),
any(
CanWallJump,
all(
GravitySuit,
CanFly
)
)
),
"Chozodia Ruins Test Reward": CanReachLocation("Chozo Ghost"),
"Chozo Ghost": all(
MotherBrainBoss,
RuinsTestEscape
),
}
chozodia_under_tube = {
"Chozodia Bomb Maze": all(
MorphBall,
CanBallJump,
any(
CanIBJ,
all(
PowerGrip,
any(
HiJump,
CanWallJump,
SpaceJump
)
),
all(
Trick("Chozodia Under Tube Items Ballspark"),
CanHiSpringBall
)
),
any(
Bomb,
PowerBombCount(3)
)
),
"Chozodia Zoomer Maze": any(
CanIBJ,
all(
PowerGrip,
CanBallJump
),
Trick("Chozodia Under Tube Items Ballspark"),
),
"Chozodia Left of Glass Tube": all(
SpeedBooster,
CanReachEntrance("Chozodia Glass Tube -> Chozo Ruins") # Required to access a save station after collecting to warp if necessary
),
"Chozodia Right of Glass Tube": all(
PowerBombs,
any(
CanFly,
all(
NormalLogic,
SpeedBooster,
CanVerticalWall
)
)
)
}
chozodia_upper_mothership = {
"Chozodia Pirate Pitfall Trap": all(
Missiles,
any(
SuperMissiles,
all(
CanReachEntrance("Chozodia Upper Mothership -> Deep Mothership"),
PowerBombs
)
),
any(
all(
CanBombTunnelBlock,
CanFlyWall
),
all(
NormalLogic, # doable without falling down using screw or by leaving the room then returning
CanSingleBombBlock
)
)
),
"Chozodia Behind Workbot": all(
Missiles,
any(
CanFly,
CanHiGrip,
CanHiWallJump
)
)
}
chozodia_lower_mothership = {
"Chozodia Ceiling Near Map Station": Missiles,
"Chozodia Southeast Corner in Hull": all(
any(
SuperMissiles,
any(
Bomb,
PowerBombCount(2)
),
),
CanVerticalWall,
PowerBombs
)
}
chozodia_pb_area = {
"Chozodia Original Power Bomb": None,
"Chozodia Next to Original Power Bomb": all(
any(
Bomb,
PowerBombCount(3)
),
CanFly
)
}
chozodia_mecha_ridley_hall = {
"Chozodia Under Mecha Ridley Hallway": SpeedBooster,
"Mecha Ridley": all(
MechaRidleyCombat,
CanEnterHighMorphTunnel,
CanBallJump,
PlasmaBeam, # To defeat black pirates
ReachedGoal
),
"Chozodia Space Pirate's Ship": MechaRidleyBoss
}
access_rules = {
**brinstar_start,
**brinstar_main,
**brinstar_top,
**brinstar_varia_area,
**brinstar_pasthives,
**kraid_main,
**kraid_acidworm_area,
**kraid_left_shaft,
**kraid_bottom,
**norfair_main,
**norfair_right_shaft,
**norfair_upper_right,
**norfair_behind_ice,
**norfair_under_brinstar_elevator,
**norfair_lowerrightshaft,
**norfair_lowerrightshaft_by_hijump,
**lower_norfair,
**norfair_screwattack,
**norfair_behind_superdoor,
**norfair_bottom,
**ridley_main,
**ridley_left_shaft,
**ridley_sw_puzzle,
**ridley_right_shaft,
**ridley_right_speed_puzzles,
**ridley_central,
**ridley_room,
**tourian,
**crateria_main,
**crateria_upper_right,
**crateria_powergrip,
**chozodia_ruins_crateria_entrance,
**chozodia_ruins_test,
**chozodia_under_tube,
**chozodia_upper_mothership,
**chozodia_lower_mothership,
**chozodia_pb_area,
**chozodia_mecha_ridley_hall
}
for i in locations:
location = world.multiworld.get_location(i, world.player)
try:
if access_rules[i]:
add_rule(location, access_rules[i].create_rule(world))
except KeyError:
continue
# Regional connection requirements
# brinstar main to past-hives, top to past-hives is different
def brinstar_past_hives():
return all(
MorphBall,
Missiles,
any(
NormalCombat,
MissileCount(10),
SuperMissiles,
LongBeam,
ChargeBeam,
IceBeam,
WaveBeam,
PlasmaBeam,
ScrewAttack
)
)
def brinstar_main_to_brinstar_top():
return any(
all(
CanSingleBombBlock,
CanBallJump
),
Trick("Brinstar Top Access Damage Boost")
)
def brinstar_pasthives_to_brinstar_top():
return all(
any(
CanFly,
all(
IceBeam,
CanHiWallJump
)
),
CanBallJump
)
def brinstar_top_to_varia():
return all(
any(
SpaceJump,
CanHorizontalIBJ,
CanHiGrip,
Trick("Varia Area Access Enemy Freeze"),
Trick("Varia Area Access Get-Around Walljump"),
Trick("Varia Area Access Tricky Spark")
),
CanBallJump
)
def brinstar_crateria_ballcannon():
return all(
PowerBombs,
CanBallCannon,
CanVerticalWall,
)
# used for the items in this area as well as determining whether the ziplines can be activated
def kraid_upper_right():
return all(
Missiles,
CanBallCannon,
any( # Getting to the top of the right shaft
CanFlyWall,
PowerGrip,
Trick("Kraid Right Shaft Balljump Climb")
),
any( # Getting up to the top door of the right shaft
CanVertical,
Trick("Kraid Right Shaft Enemy Freeze")
),
any( # Getting through the hole in the next room
CanHorizontalIBJ,
PowerGrip,
all(
IceBeam,
CanBallJump
),
all(
GravitySuit,
CanIBJ
),
all(
any(
HazardRuns,
VariaSuit
),
Trick("Balljump to IBJ From Acid"),
)
)
)
# access to lower kraid
def kraid_left_shaft_access():
return all(
any(
CanHorizontalIBJ,
PowerGrip,
all(
GravitySuit,
CanIBJ
),
all(
NormalLogic,
CanHiSpringBall
),
Trick("Rising Midair Morph With Space Jump")
),
CanBallJump,
CanBombTunnelBlock,
any(
Ziplines,
SpaceJump,
all(
GravitySuit,
any(
CanIBJ,
Trick("Acid Worm Skip Tricky Spark")
)
),
Trick("Acid Worm Skip Grip Only"),
Trick("Acid Worm Skip Grip And Bombs"),
Trick("Acid Worm Skip Bomb Only")
)
)
def kraid_left_shaft_to_bottom():
return UnknownItem2
def kraid_bottom_to_lower_norfair():
return Trick("Kraid-Norfair Shortcut")
def norfair_main_to_crateria():
return all(
MorphBall,
any(
CanLongBeam(1),
CanBallspark
),
any(
LayoutPatches("crateria_water_speedway"),
CanEnterMediumMorphTunnel
)
)
def norfair_right_shaft_access():
return any(
CanVertical,
SpeedBooster,
Trick("Norfair Big Room Entrance Enemy Freeze")
)
def norfair_upper_right_shaft():
return any(
CanVerticalWall,
all(
IceBeam,
any(
NormalLogic,
HardMode
)
)
)
def norfair_behind_ice_beam():
return all(
CanReachLocation("Norfair Ice Beam"),
any(
CanLongBeam(2),
WaveBeam
),
MorphBall,
any( # Climbing the ripper shaft and getting to the statue
SpaceJump,
CanHorizontalIBJ,
CanWallJump, # TODO if the Chozo statues ever stand up, this WallJump rule needs to change for Hard
all(
IceBeam,
any(
NormalMode,
CanVertical,
Trick("Behind Ice Beam Shaft Hard Mode Enemy Freeze")
)
)
),
any(
all(
PowerGrip,
any(
CanWallJump,
SpaceJump,
IceBeam
)
),
CanIBJ,
all(
IceBeam,
CanHiSpringBall,
)
)
)
def norfair_behind_ice_to_bottom():
return Trick("Norfair-Ridley Shortcut")
def norfair_shaft_to_under_elevator():
return any(
SpeedBooster,
all(
ScrewAttack,
any(
CanFlyWall,
CanHiGrip
)
)
)
# under elevator to lower right shaft
def norfair_lower_right_shaft():
LRSByHiJumpRule = norfair_lower_right_shaft_to_lrs_by_hijump()
LowerNorfairAccess = norfair_lower_right_shaft_to_lower_norfair()
return any(
all(
ScrewAttack,
any(
CanFlyWall,
CanHiGrip
)
),
all(
SpeedBooster,
any( # escape via ballcannon
all(
LRSByHiJumpRule,
any(
Missiles,
CanVertical
),
CanBallCannon,
),
# to reach a save station and warp out
LowerNorfairAccess
)
)
)
# This region only contains the Lower Right Shaft By Hi-Jump item, and serves a pathfinding purpose
def norfair_lower_right_shaft_to_lrs_by_hijump():
return all(
any(
CanIBJ,
CanHiGrip,
all(
SpaceJump,
PowerGrip
),
Trick("Norfair Right Shaft Get-Around Walljump")
),
any( # escape
CanIBJ,
all(
PowerGrip,
any(
SpaceJump,
CanWallJump
)
),
all(
CanBallCannon,
any(
Missiles,
CanVertical
)
)
)
)
def by_hijump_to_lower_right_shaft():
return any(
CanIBJ,
all(
MorphBall,
PowerGrip,
CanFlyWall
)
)
def norfair_lower_shaft_to_under_elevator():
return all(
ScrewAttack,
any(
CanFlyWall,
CanHiGrip
)
)
def norfair_lower_right_shaft_to_lower_norfair():
return all(
Missiles,
CanBombTunnelBlock,
any(
VariaSuit,
Trick("Norfair Right Shaft to Lower Hellrun - Normal"),
Trick("Norfair Right Shaft to Lower Hellrun - Minimal")
),
any( # First heated room
SpaceJump,
CanWallJump,
CanHorizontalIBJ,
all(
GravitySuit,
any(
CanHiGrip,
CanIBJ
)
),
all(
HazardRuns,
Trick("Balljump to IBJ From Acid"),
),
all(
CanEnterMediumMorphTunnel,
CanBallJump,
any(
PowerGrip,
all(
CanBallJump,
NormalLogic # Slightly tight bomb jump, but you can do it with just one bomb
)
)
)
),
any( # Second heated room
SpaceJump,
any(
CanHorizontalIBJ,
all(
GravitySuit,
CanIBJ
)
),
all(
any(
Bomb,
PowerBombCount(2), # One PB is needed to get to this room, then another to clear the runway
ScrewAttack
),
SpeedBooster
)
)
)
def lower_norfair_to_screwattack():
return any(
all(
ScrewAttack,
any(
CanWallJump,
SpaceJump
)
),
all(
NormalLogic,
MissileCount(5),
any(
CanFlyWall,
Trick("Screw Attack Access Enemy Freeze")
)
),
Trick("Screw Attack Access Shinespark")
)
# This is necessary if your only way to the Screw Attack region is the ballcannon near the Ridley elevator
# e.g. you don't have Varia/hellruns but can take the Ridley shortcut
def screw_to_lower_norfair():
return any(
MissileCount(4),
ScrewAttack
)
def lower_norfair_to_kraid():
return all(
Trick("Kraid-Norfair Shortcut"),
any(
CanIBJ,
PowerGrip,
CanBallspark,
all(
CanSpringBall,
IceBeam
)
)
)
# The two items in Lower Norfair behind the Super Missile door right under the Screw Attack area
def lower_norfair_to_spaceboost_room():
return all(
SuperMissiles,
any(
SpeedBooster,
Bomb,
PowerBombCount(2),
all(
WaveBeam,
LongBeam,
any(
PowerGrip,
all(
GravitySuit,
CanEnterMediumMorphTunnel
)
)
)
),
CanVertical
)
def lower_norfair_to_bottom_norfair():
return all(
MissileCount(2),
SpeedBooster,
any(
VariaSuit,
HazardRuns
),
any(
WaveBeam,
Trick("Lower Norfair Wave Beam Skip Tricky Spark"),
Trick("Lower Norfair Wave Beam Skip With Bombs")
),
any( # Escape from under the first larva
CanBallJump,
LayoutPatches("norfair_larvae_room")
),
CanEnterMediumMorphTunnel,
any( # First larva
WaveBeam,
PowerBombCount(2),
all(
PowerBombs,
any(
PlasmaBeam,
Bomb
)
),
Trick("Norfair Larvae Room Missiles")
),
any( # Second larva
PlasmaBeam,
CanBombTunnelBlock
)
)
# Needed for Kraid -> Norfair shortcut, so this rule is for getting to Hi-Jump location from that entrance
def lower_norfair_to_lower_right_shaft():
return all(
any(
PowerGrip,
HiJump,
SpaceJump,
CanWallJump,
CanHorizontalIBJ,
all(
CanIBJ,
any(
IceBeam,
GravitySuit
)
)
),
CanBombTunnelBlock,
any(
VariaSuit,
Trick("Lower Norfair to Right Shaft Hellrun - Normal"),
Trick("Lower Norfair to Right Shaft Hellrun - Minimal")
)
)
def bottom_norfair_to_lower_shaft_by_hijump():
return any(
all(
Missiles,
CanReachLocation("Norfair Right Shaft Bottom"),
any(
CanBombTunnelBlock,
WaveBeam
),
CanFlyWall,
),
all(
NormalLogic,
SpeedBooster,
CanFlyWall
),
)
def bottom_norfair_to_right_shaft():
return SpeedBooster
def bottom_norfair_to_ridley():
return any(
PowerBombs,
all(
any(
MissileCount(20),
SuperMissileCount(8),
all(
NormalCombat,
any(
MissileTanks(1),
SuperMissileCount(6),
)
)
),
any(
IceBeam,
SpaceJump,
NormalLogic # You can hit the vines without any items, it's just a little tricky
)
)
)
def bottom_norfair_to_screw():
return all(
RidleyBoss,
SpeedBooster,
any(
CanBallCannon,
NormalLogic
),
any(
IceBeam,
CanVerticalWall
)
)
def ridley_main_to_left_shaft():
return all(
SuperMissiles,
any(
CanVerticalWall,
IceBeam
),
any(
VariaSuit,
Trick("Ridley Hellrun - Normal"),
Trick("Ridley Hellrun - Minimal"),
all(
CanBombTunnelBlock,
any(
CanFly,
Trick("Ridley Fake Floor Skip"),
)
)
),
MorphBall,
any(
NormalCombat,
EnergyTanks(2),
VariaSuit,
GravitySuit
)
)
# shortcut to the right of elevator
def ridley_main_to_right_shaft():
return all(
Trick("Ridley Right Shaft Shortcut"),
any(
NormalCombat,
EnergyTanks(2),
VariaSuit,
GravitySuit
)
)
def ridley_left_shaft_to_sw_puzzle():
return all(
SpeedBooster,
any(
CanVerticalWall,
IceBeam
)
)
# The alcove to the right of the right shaft
def ridley_speed_puzzles_access():
return all(
SpeedBooster,
CanVerticalWall
)
# getting into the gap at the start of "ball room" and subsequently into the general area of ridley himself
def ridley_right_shaft_to_central():
return CanEnterMediumMorphTunnel
def ridley_right_shaft_to_left_shaft():
return any(
CanIBJ,
all(
SpaceJump,
any(
PowerGrip,
all(
NormalLogic,
CanBallspark
)
),
),
Trick("Ridley Left Shaft Climb Tricky Spark")
)
# Ridley, Unknown 3, and the item behind Unknown 3
def ridley_central_to_ridley_room():
return all(
any(
Missiles,
ChargeBeam # Fun fact! you can kill the eye door with charge beam
),
RidleyCombat,
any(
CanFly,
all(
IceBeam,
CanVerticalWall
)
)
)
# TODO: Disabled for now since this warp is one-time. Later it may be repeatable, and then it might matter rarely
def tourian_to_chozodia():
return all(
MotherBrainBoss,
RuinsTestEscape
)
# Getting across the acid pits in post-MB Tourian
# Left of MB is not in this region because it requires building speed before the acid pits
def tourian_to_escape_shaft():
return all(
MotherBrainBoss,
ChozoGhostBoss,
any(
SpaceJump,
SpeedBooster,
Trick("Tourian Acid Dive - Normal"),
Trick("Tourian Acid Dive - Minimal")
)
)
# From elevator to above the Unknown Item block by the Chozo statue
def crateria_lower_to_crateria_upper_right():
return any(
all(
any(
CanVerticalWall,
CanBombTunnelBlock
),
CanBallJump,
),
all(
NormalLogic,
ScrewAttack,
any(
SpaceJump,
CanHiWallJump,
Trick("Crateria Upper Access Tricky Spark")
),
CanFlyWall # Getting up the pillars after the screw blocks
)
)
# From elevator to the left door of the Power Grip tower room
def crateria_lower_to_crateria_upper_left():
return any(
all(
CanFly,
any(
all(
PowerBombs,
SpeedBooster,
GravitySuit
),
all(
NormalLogic, # not in Simple level logic because this requires meta knowledge of the rando
LayoutPatches("crateria_water_speedway")
)
),
any(
LayoutPatches("crateria_left_of_grip"),
CanEnterHighMorphTunnel
)
),
all( # Shinespark up landing site
any(
PowerBombs,
LayoutPatches("crateria_water_speedway")
),
SpeedBooster,
GravitySuit,
any(
all(
LayoutPatches("crateria_left_of_grip"),
CanVertical
),
CanEnterHighMorphTunnel
)
)
)
# This rule is mostly escape logic, so it's the same for both upper left and upper right
def crateria_upper_to_powergrip():
return all(
CanBallJump,
any(
all(
CanVertical,
LayoutPatches("crateria_left_of_grip")
),
CanEnterHighMorphTunnel,
CanFly
)
)
# Getting across the Power Grip tower room
def crateria_upper_leftright_connection():
return any(
CanFly,
all(
NormalLogic, # Tight jump
CanHiGrip
)
)
# Upper Crateria door to Ruins, the two items right by it, and the Triple Crawling Pirates
def crateria_upper_to_chozo_ruins():
return all(
PowerBombs,
MorphBall,
Missiles,
any(
CanFly,
CanReachLocation("Crateria Northeast Corner"),
Trick("Crateria-Chozodia Door Get-Around Walljump")
),
any(
MotherBrainBoss,
Requirement.setting_is("chozodia_access", 0)
)
)
def crateria_left_to_landing_site():
return any(
SpeedBooster,
CanFly,
all(
NormalLogic,
CanHiWallJump
)
)
def crateria_to_tourian():
return all(
MotherBrainBoss,
ChozoGhostBoss,
SuperMissiles
)
# Ruins to Chozo Ghost, the three items in that general area, and the lava dive item
def chozo_ruins_to_ruins_test():
return all(
MorphBall,
PowerBombCount(2), # 2 PBs ALWAYS required at minimum, but you may need many more
any(
all(
Bomb,
any(
NormalMode,
PowerBombCount(4) # on Hard a save room is disabled, so you cannot refill PBs, requiring more
)
),
PowerBombCount(8),
all(
NormalMode,
PowerBombCount(5),
),
all( # Skips one PB on the slow-crumble morph tunnel
any(
PowerBombCount(7),
all(
NormalMode,
PowerBombCount(4)
)
),
any(
ScrewAttack,
WaveBeam
),
NormalLogic
),
all( # Skips the Triple Crawling Pirates room and a bomb chain but doesn't skip the crumble tunnel
any(
PowerBombCount(5), # Saves 2 on Hard
all(
NormalMode,
PowerBombCount(4), # Only saves 1 on Normal because you can refill
)
),
CanFlyWall,
MissileCount(3),
Missiles,
CanFlyWall
),
all( # Skips everything possible, but still only PBs
CanFlyWall,
any(
ScrewAttack,
WaveBeam
),
Missiles,
PowerBombCount(4), # technically should be 3 on Normal, but Normal can't have 3 max without having 4
NormalLogic,
CanFlyWall
)
),
CanVerticalWall,
ChozodiaCombat,
)
# Potentially useful for closed Chozodia post-MB warp, if that ever becomes a valid path
def ruins_test_to_ruins():
return all(
ChozoGhostBoss,
RuinsTestEscape,
any(
all( # Through the lava
any(
CanWallJump,
all(
GravitySuit,
CanFly
)
),
any(
ScrewAttack,
all(
NormalLogic,
Missiles,
any(
Bomb,
PowerBombCount(2)
)
)
),
any(
GravitySuit,
Trick("Chozodia Lava Dive Escape - Normal"),
Trick("Chozodia Lava Dive Escape - Minimal")
)
),
all( # Or going all the way back through the ruins
NormalLogic,
any(
PowerBombCount(4),
all(
Bomb,
PowerBombCount(2)
)
),
CanFlyWall,
ScrewAttack
)
)
)
def chozo_ruins_to_chozodia_tube():
return any(
all(
NormalLogic, # It's a kinda tricky walljump but not really trick worthy
CanWallJump
),
CanFly
)
# Specifically getting to the room with Crateria Upper Door location. Might need another empty region for region rando
def chozodia_tube_to_chozo_ruins():
return all(
any(
CanFlyWall,
CanHiGrip
),
CanBombTunnelBlock
)
def crateria_to_under_tube():
return all(
PowerBombs,
MorphBall,
any(
SpeedBooster,
CanFlyWall,
CanHiGrip
),
any(
MotherBrainBoss,
Requirement.setting_is("chozodia_access", 0)
)
)
def under_tube_to_tube():
return any(
SpeedBooster,
all(
CanFly,
PowerBombs
)
)
def under_tube_to_crateria():
return any(
CanIBJ,
all(
PowerGrip,
CanFlyWall
),
Trick("Chozodia Under Tube Items Ballspark") # Not an item but same idea so might as well reuse it
)
def tube_to_under_tube():
return any(
PowerBombCount(3), # most paths here require breaking a bomb chain on the way here and back
all(
Bomb,
PowerBombs
)
)
def chozodia_tube_to_mothership_central():
return all(
ChozodiaCombat,
any(
CanFly,
all(
CanWallJump,
any(
HiJump,
Trick("Chozodia Pirates Enemy Freezes")
)
)
)
)
# access to the map station
def mothership_central_to_lower():
return all(
any(
PowerBombCount(2),
all(
Bomb,
PowerBombs
)
),
any( # Getting to the save room
Missiles,
CanHiGrip,
CanHiWallJump,
CanFly,
all(
Trick("Chozodia Pirates Enemy Freezes"),
any(
HiJump,
PowerGrip,
CanWallJump
)
)
)
)
# accessing the missile door just under the Behind Workbot item
def mothership_central_to_upper():
return all(
Missiles,
any(
Bomb,
PowerBombCount(2)
),
any(
all(
ScrewAttack,
any(
CanWallJump,
SpaceJump,
all(
HiJump,
any(
PowerGrip,
CanIBJ
)
)
)
),
all(
MissileCount(5),
any(
CanFly,
CanHiGrip,
CanHiWallJump,
all(
Trick("Chozodia Pirates Enemy Freezes"),
CanVerticalWall
)
)
),
# the low% way
all(
any(
MissileCount(4),
ScrewAttack
),
any(
CanFly,
CanHiGrip,
CanHiWallJump
),
any(
Bomb,
PowerBombCount(3)
),
any(
ScrewAttack,
MissileCount(5),
Bomb,
PowerBombCount(4)
)
)
)
)
def mothership_lower_to_upper():
return all(
CanBombTunnelBlock,
any(
CanFly,
CanHiGrip,
CanHiWallJump # HJWJ required to get from the blue ship to the room under workbot; just WJ doesn't work
)
)
# the long way around - in case you don't have enough PBs
def mothership_upper_to_lower():
return all(
any(
CanFlyWall,
CanHiGrip
),
any(
all(
NormalMode,
MissileCount(2),
CanBombTunnelBlock
),
all(
MissileCount(4),
Bomb # On Hard, you'd need 2 PBs to go this way, so the more direct central -> lower route is better
)
)
)
# to the room right past Pirate Pitfall Trap
def mothership_upper_to_deep_mothership():
return any(
all(
Missiles,
any(
CanFly,
Trick("Mothership Upper Access Walljump")
)
),
# shortcut, going through Pirate Pitfall Trap
all(
SuperMissiles,
PowerBombs,
any(
CanFlyWall,
NormalLogic # Leave and return to the room after PBing, the bomb blocks never reform
)
)
)
def deep_mothership_to_cockpit():
return all(
CanFlyWall,
any(
Bomb,
PowerBombCount(4)
),
ChozodiaCombat
)
def cockpit_to_original_pb():
return all(
any( # cannot IBJ to escape to cockpit
CanWallJump,
HiJump,
PowerGrip,
SpaceJump
),
any(
Bomb,
PowerBombCount(2)
),
any(
CanIBJ,
all(
PowerGrip,
any(
CanFlyWall,
HiJump
)
),
Trick("Alpha PB Area Ice Escape")
)
)
def cockpit_to_mecha_ridley():
return all(
CanBombTunnelBlock,
any(
all(
PowerBombs,
CanVertical
),
CanIBJ,
PowerGrip,
Trick("Chozodia Pirates Enemy Freezes")
),
any(
CanBallJump,
PowerGrip
),
any(
all(
PowerBombs,
any(
Bomb,
PowerBombCount(2),
all(
NormalLogic,
MissileCount(4)
)
),
),
Trick("Mecha Ridley Hall PB Skip")
)
)