Files
dockipelago/worlds/apeescape/Rules.py
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

2999 lines
190 KiB
Python

from typing import TYPE_CHECKING
from BaseClasses import Region, Item, ItemClassification, CollectionState
from .Regions import connect_regions, ApeEscapeLevel
from .Strings import AEItem, AEDoor, AELocation
from .RAMAddress import RAM
if TYPE_CHECKING:
from . import ApeEscapeWorld
def set_rules(world: "ApeEscapeWorld"):
# Detect if connected with UT and put the shuffled order back into the initialize_level_list function
if hasattr(world.multiworld, "re_gen_passthrough"):
levelids = world.passthrough["entranceids"]
firstroomids = world.passthrough["firstrooms"]
world.levellist = initialize_level_list(levelids)
world.firstrooms = initialize_room_list(world, RAM.roomsperlevel, levelids, firstroomids)
else:
# Normal world generation
world.levellist = initialize_level_list()
# If entrances aren't shuffled, then we don't need to shuffle the entrances.
if (world.options.entrance != 0x00):
world.random.shuffle(world.levellist)
# Some levels need to be kept at a specific entrance - put those back.
world.levellist = fixed_levels(world.levellist, world.options.entrance, world.options.coin, world.options.goal)
world.firstrooms = initialize_room_list(world, RAM.roomsperlevel)
world.levellist = set_calculated_level_data(world.levellist, world.options.unlocksperkey, world.options.goal, world.options.coin)
# Make a copy of the list for passing to the client for entrance shuffle purposes. We know this list has the levels sorted in the order they'd be presented in-game (so whatever is at the Fossil Field entrance first, etc.)
world.entranceorder = list(world.levellist)
# If entrances weren't shuffled, then this list is already sorted. We sort the list for ease of setting up access rules in the logic files.
if (world.options.entrance != 0x00):
world.levellist.sort()
set_entrances(world, world.options.logic)
set_doors(world, world.options.logic)
set_transitions(world, world.options.logic)
set_locations(world, world.options.logic)
if world.using_ut:
# For Out-of-logic checks in UT:
# Re-gen entries/region rules with max difficulty (Expert) and glitched UT item
set_entrances(world, "expert")
set_doors(world, "expert")
set_transitions(world, "expert")
set_locations(world, "expert")
# Entrances are specifically connections between the Time Station (level select) and a level.
# If we ever want to change the starting room of a level, this is where we would set that room.
def set_entrances(self, logic):
connect_regions(self, "Menu", AEDoor.TIME_ENTRY.value, lambda state: True)
roomperlevelsKeys = list(RAM.roomsperlevel.keys())
roomperlevelsValues = list(RAM.roomsperlevel.values())
LevelperFirstRooms = []
RoomRegion = []
for y in self.firstrooms:
LevelperFirstRooms.append(
roomperlevelsKeys[[roomperlevelsValues[x].__contains__(y) for x in range(0, 22)].index(True)])
RoomRegion.append(RAM.roomstostring[y])
SortedEntries = [x for _, x in sorted(zip(LevelperFirstRooms, RoomRegion))]
connect_regions(self, "Menu", SortedEntries[0], lambda state: Keys(state, self, self.levellist[0].keys))
connect_regions(self, "Menu", SortedEntries[1], lambda state: Keys(state, self, self.levellist[1].keys))
connect_regions(self, "Menu", SortedEntries[2], lambda state: Keys(state, self, self.levellist[2].keys))
connect_regions(self, "Menu", SortedEntries[3], lambda state: Keys(state, self, self.levellist[3].keys))
connect_regions(self, "Menu", SortedEntries[4], lambda state: Keys(state, self, self.levellist[4].keys))
connect_regions(self, "Menu", SortedEntries[5], lambda state: Keys(state, self, self.levellist[5].keys))
connect_regions(self, "Menu", SortedEntries[6], lambda state: Keys(state, self, self.levellist[6].keys))
connect_regions(self, "Menu", SortedEntries[7], lambda state: Keys(state, self, self.levellist[7].keys))
connect_regions(self, "Menu", SortedEntries[8], lambda state: Keys(state, self, self.levellist[8].keys))
connect_regions(self, "Menu", SortedEntries[9], lambda state: Keys(state, self, self.levellist[9].keys))
connect_regions(self, "Menu", SortedEntries[10], lambda state: Keys(state, self, self.levellist[10].keys))
connect_regions(self, "Menu", SortedEntries[11], lambda state: Keys(state, self, self.levellist[11].keys))
connect_regions(self, "Menu", SortedEntries[12], lambda state: Keys(state, self, self.levellist[12].keys))
connect_regions(self, "Menu", SortedEntries[13], lambda state: Keys(state, self, self.levellist[13].keys))
connect_regions(self, "Menu", SortedEntries[14], lambda state: Keys(state, self, self.levellist[14].keys))
connect_regions(self, "Menu", SortedEntries[15], lambda state: Keys(state, self, self.levellist[15].keys))
connect_regions(self, "Menu", SortedEntries[16], lambda state: Keys(state, self, self.levellist[16].keys))
connect_regions(self, "Menu", SortedEntries[17], lambda state: Keys(state, self, self.levellist[17].keys))
connect_regions(self, "Menu", SortedEntries[18], lambda state: Keys(state, self, self.levellist[18].keys))
connect_regions(self, "Menu", SortedEntries[19], lambda state: Keys(state, self, self.levellist[19].keys))
connect_regions(self, "Menu", SortedEntries[20], lambda state: Keys(state, self, self.levellist[20].keys))
if self.options.goal == "ppm": # If Specter 2 is the goal, require enough keys and all monkeys.
connect_regions(self, "Menu", SortedEntries[21], lambda state: Keys(state, self, self.levellist[21].keys) and HasAllMonkeys(state, self))
elif self.options.goal == "ppmtoken": # If Specter 2 token is the goal, require enough keys and tokens.
connect_regions(self, "Menu", SortedEntries[21], lambda state: Keys(state, self, self.levellist[21].keys) and Tokens(state, self, min(self.options.requiredtokens, self.options.totaltokens)))
elif self.options.goal == "tokenhunt" or self.options.goal == "mmtoken": # If other token goal, just require keys.
connect_regions(self, "Menu", SortedEntries[21], lambda state: Keys(state, self, self.levellist[21].keys))
# If the goal is not token hunt, then there is a victory item on the worlds' final boss.
if self.options.goal != "tokenhunt":
# Redundant, but maybe relevant if we get more goals in the future
if self.options.goal in ("mm","mmtoken","ppm","ppmtoken"):
self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player)
else:
self.multiworld.completion_condition[self.player] = lambda state: Tokens(state, self, min(self.options.requiredtokens, self.options.totaltokens))
# A door is defined as a connection between rooms, typically bi-directional.
# For the logic behind door shuffle, this is the section to change.
def set_doors(self, logic):
# I'm not sure if these have to be manually connected in both directions? There are a few one-ways in here, so probably better to be explicit?
# Time Station
connect_regions(self, AEDoor.TIME_MAIN_TRAINING.value, AEDoor.TIME_TRAINING_MAIN.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_MAIN_MINIGAME.value, AEDoor.TIME_MINIGAME_MAIN.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_TRAINING_MAIN.value, AEDoor.TIME_MAIN_TRAINING.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_MINIGAME_MAIN.value, AEDoor.TIME_MAIN_MINIGAME.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_TRAINING_MAIN.value, AEDoor.TIME_TRAINING_WATERNET.value,
lambda state: True)
# Fossil Field (level contains no doors)
# Primordial Ooze (level contains no doors)
# Molten Lava
connect_regions(self, AEDoor.ML_ENTRY_VOLCANO.value, AEDoor.ML_VOLCANO_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.ML_ENTRY_TRICERATOPS.value, AEDoor.ML_TRICERATOPS_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.ML_VOLCANO_ENTRY.value, AEDoor.ML_ENTRY_VOLCANO.value,
lambda state: True)
connect_regions(self, AEDoor.ML_TRICERATOPS_ENTRY.value, AEDoor.ML_ENTRY_TRICERATOPS.value,
lambda state: True)
# Thick Jungle
connect_regions(self, AEDoor.TJ_ENTRY_MUSHROOM.value, AEDoor.TJ_MUSHROOM_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_ENTRY_FISH.value, AEDoor.TJ_FISH_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_ENTRY_BOULDER.value, AEDoor.TJ_BOULDER_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AEDoor.TJ_ENTRY_MUSHROOM.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_FISH_ENTRY.value, AEDoor.TJ_ENTRY_FISH.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_FISH_TENT.value, AEDoor.TJ_TENT_FISH.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_TENT_FISH.value, AEDoor.TJ_FISH_TENT.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AEDoor.TJ_BOULDER_TENT.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_BOULDER_ENTRY.value, AEDoor.TJ_ENTRY_BOULDER.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_BOULDER_TENT.value, AEDoor.TJ_TENT_BOULDER.value,
lambda state: True)
# Dark Ruins
connect_regions(self, AEDoor.DR_OUTSIDE_FENCE.value, AEDoor.DR_FAN_OUTSIDE_FENCE.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_HOLE.value, AEDoor.DR_FAN_OUTSIDE_HOLE.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_OBELISK_BOTTOM.value, AEDoor.DR_OBELISK_BOTTOM.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_OBELISK_TOP.value, AEDoor.DR_OBELISK_TOP.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_WATER_BUTTON.value, AEDoor.DR_WATER_SIDE.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_WATER_LEDGE.value, AEDoor.DR_WATER_LEDGE.value,
lambda state: True)
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_FENCE.value, AEDoor.DR_OUTSIDE_FENCE.value,
lambda state: True)
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_HOLE.value, AEDoor.DR_OUTSIDE_HOLE.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OBELISK_BOTTOM.value, AEDoor.DR_OUTSIDE_OBELISK_BOTTOM.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OBELISK_TOP.value, AEDoor.DR_OUTSIDE_OBELISK_TOP.value,
lambda state: True)
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AEDoor.DR_OUTSIDE_WATER_BUTTON.value,
lambda state: True)
connect_regions(self, AEDoor.DR_WATER_LEDGE.value, AEDoor.DR_OUTSIDE_WATER_LEDGE.value,
lambda state: True)
# Cryptic Relics
connect_regions(self, AEDoor.CR_ENTRY_SIDE_ROOM.value, AEDoor.CR_SIDE_ROOM_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.CR_ENTRY_MAIN_RUINS.value, AEDoor.CR_MAIN_RUINS_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.CR_SIDE_ROOM_ENTRY.value, AEDoor.CR_ENTRY_SIDE_ROOM.value,
lambda state: True)
connect_regions(self, AEDoor.CR_MAIN_RUINS_ENTRY.value, AEDoor.CR_ENTRY_MAIN_RUINS.value,
lambda state: True)
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AEDoor.CR_PILLAR_ROOM_MAIN_RUINS.value,
lambda state: True)
connect_regions(self, AEDoor.CR_PILLAR_ROOM_MAIN_RUINS.value, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value,
lambda state: True)
# Stadium Attack (level contains no doors)
# Crabby Beach
connect_regions(self, AEDoor.CB_ENTRY_SECOND_ROOM.value, AEDoor.CB_SECOND_ROOM_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.CB_SECOND_ROOM_ENTRY.value, AEDoor.CB_ENTRY_SECOND_ROOM.value,
lambda state: True)
# Coral Cave
connect_regions(self, AEDoor.CCAVE_ENTRY_SECOND_ROOM.value, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AEDoor.CCAVE_ENTRY_SECOND_ROOM.value,
lambda state: True)
# Dexter's Island
connect_regions(self, AEDoor.DI_ENTRY_STOMACH.value, AEDoor.DI_STOMACH_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.DI_STOMACH_ENTRY.value, AEDoor.DI_ENTRY_STOMACH.value,
lambda state: True)
connect_regions(self, AEDoor.DI_STOMACH_SLIDE_ROOM.value, AEDoor.DI_SLIDE_ROOM_STOMACH.value,
lambda state: True)
connect_regions(self, AEDoor.DI_SLIDE_ROOM_STOMACH.value, AEDoor.DI_STOMACH_SLIDE_ROOM.value,
lambda state: True)
connect_regions(self, AEDoor.DI_SLIDE_ROOM_GALLERY.value, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value,
lambda state: True)
connect_regions(self, AEDoor.DI_SLIDE_ROOM_GALLERY_WATER.value, AEDoor.DI_GALLERY_SLIDE_ELEVATOR.value,
lambda state: True)
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value, AEDoor.DI_SLIDE_ROOM_GALLERY.value,
lambda state: True)
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ELEVATOR.value, AEDoor.DI_SLIDE_ROOM_GALLERY_WATER.value,
lambda state: True)
connect_regions(self, AEDoor.DI_GALLERY_TENTACLE.value, AEDoor.DI_TENTACLE.value,
lambda state: True)
connect_regions(self, AEDoor.DI_TENTACLE.value, AEDoor.DI_GALLERY_TENTACLE.value,
lambda state: True)
# Snowy Mammoth (level contains no doors)
# Frosty Retreat
connect_regions(self, AEDoor.FR_ENTRY_CAVERNS.value, AEDoor.FR_CAVERNS_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.FR_CAVERNS_ENTRY.value, AEDoor.FR_ENTRY_CAVERNS.value,
lambda state: True)
connect_regions(self, AEDoor.FR_CAVERNS_WATER.value, AEDoor.FR_WATER_CAVERNS.value,
lambda state: True)
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AEDoor.FR_CAVERNS_WATER.value,
lambda state: True)
# Hot Springs
connect_regions(self, AEDoor.HS_ENTRY_HOT_SPRING.value, AEDoor.HS_HOT_SPRING.value,
lambda state: True)
connect_regions(self, AEDoor.HS_ENTRY_POLAR_BEAR_CAVE.value, AEDoor.HS_POLAR_BEAR_CAVE.value,
lambda state: True)
connect_regions(self, AEDoor.HS_HOT_SPRING.value, AEDoor.HS_ENTRY_HOT_SPRING.value,
lambda state: True)
connect_regions(self, AEDoor.HS_POLAR_BEAR_CAVE.value, AEDoor.HS_ENTRY_POLAR_BEAR_CAVE.value,
lambda state: True)
# Gladiator Attack (level contains no doors)
# Sushi Temple
connect_regions(self, AEDoor.ST_ENTRY_TEMPLE.value, AEDoor.ST_TEMPLE.value,
lambda state: True)
connect_regions(self, AEDoor.ST_ENTRY_WELL.value, AEDoor.ST_WELL.value,
lambda state: True)
connect_regions(self, AEDoor.ST_TEMPLE.value, AEDoor.ST_ENTRY_TEMPLE.value,
lambda state: True)
connect_regions(self, AEDoor.ST_WELL.value, AEDoor.ST_ENTRY_WELL.value,
lambda state: True)
# Wabi Sabi Wall
connect_regions(self, AEDoor.WSW_ENTRY_GONG.value, AEDoor.WSW_GONG_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.WSW_GONG_ENTRY.value, AEDoor.WSW_ENTRY_GONG.value,
lambda state: True)
connect_regions(self, AEDoor.WSW_GONG_MIDDLE.value, AEDoor.WSW_MIDDLE_GONG.value,
lambda state: True)
connect_regions(self, AEDoor.WSW_MIDDLE_GONG.value, AEDoor.WSW_GONG_MIDDLE.value,
lambda state: True)
connect_regions(self, AEDoor.WSW_MIDDLE_OBSTACLE.value, AEDoor.WSW_OBSTACLE_MIDDLE.value,
lambda state: True)
connect_regions(self, AEDoor.WSW_OBSTACLE_MIDDLE.value, AEDoor.WSW_MIDDLE_OBSTACLE.value,
lambda state: True)
connect_regions(self, AEDoor.WSW_OBSTACLE_BARREL.value, AEDoor.WSW_BARREL_OBSTACLE.value,
lambda state: True)
connect_regions(self, AEDoor.WSW_BARREL_OBSTACLE.value, AEDoor.WSW_OBSTACLE_BARREL.value,
lambda state: True)
# Crumbling Castle
connect_regions(self, AEDoor.CC_ENTRY_CASTLE.value, AEDoor.CC_CASTLEMAIN_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.CC_ENTRY_BELL.value, AEDoor.CC_BELL_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.CC_ENTRY_BASEMENT.value, AEDoor.CC_BASEMENT_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.CC_ENTRY_BOSS.value, AEDoor.CC_BOSS_ROOM.value,
lambda state: True)
connect_regions(self, AEDoor.CC_CASTLEMAIN_ENTRY.value, AEDoor.CC_ENTRY_CASTLE.value,
lambda state: True)
connect_regions(self, AEDoor.CC_CASTLEMAIN_BELL.value, AEDoor.CC_BELL_CASTLE.value,
lambda state: True)
connect_regions(self, AEDoor.CC_CASTLEMAIN_ELEVATOR.value, AEDoor.CC_ELEVATOR_CASTLEMAIN.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BELL_ENTRY.value, AEDoor.CC_ENTRY_BELL.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BELL_CASTLE.value, AEDoor.CC_CASTLEMAIN_BELL.value,
lambda state: True)
connect_regions(self, AEDoor.CC_ELEVATOR_CASTLEMAIN.value, AEDoor.CC_CASTLEMAIN_ELEVATOR.value,
lambda state: True)
connect_regions(self, AEDoor.CC_ELEVATOR_BASEMENT.value, AEDoor.CC_BASEMENT_ELEVATOR.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BASEMENT_ENTRY.value, AEDoor.CC_ENTRY_BASEMENT.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AEDoor.CC_ELEVATOR_BASEMENT.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BASEMENT_BUTTON_DOWN.value, AEDoor.CC_BUTTON_BASEMENT_WATER.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BASEMENT_BUTTON_UP.value, AEDoor.CC_BUTTON_BASEMENT_LEDGE.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BUTTON_BASEMENT_WATER.value, AEDoor.CC_BASEMENT_BUTTON_DOWN.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BUTTON_BASEMENT_LEDGE.value, AEDoor.CC_BASEMENT_BUTTON_UP.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BOSS_ROOM.value, AEDoor.CC_ENTRY_BOSS.value,
lambda state: True)
# City Park
connect_regions(self, AEDoor.CP_OUTSIDE_SEWERS_FRONT.value, AEDoor.CP_SEWERSFRONT_OUTSIDE.value,
lambda state: True)
connect_regions(self, AEDoor.CP_OUTSIDE_BARREL.value, AEDoor.CP_BARREL_OUTSIDE.value,
lambda state: True)
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AEDoor.CP_OUTSIDE_SEWERS_FRONT.value,
lambda state: True)
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AEDoor.CP_BARREL_SEWERS_FRONT.value,
lambda state: True)
connect_regions(self, AEDoor.CP_BARREL_OUTSIDE.value, AEDoor.CP_OUTSIDE_BARREL.value,
lambda state: True)
connect_regions(self, AEDoor.CP_BARREL_SEWERS_FRONT.value, AEDoor.CP_SEWERSFRONT_BARREL.value,
lambda state: True)
# Specter's Factory
connect_regions(self, AEDoor.SF_OUTSIDE_FACTORY.value, AEDoor.SF_FACTORY_OUTSIDE.value,
lambda state: True)
connect_regions(self, AEDoor.SF_FACTORY_OUTSIDE.value, AEDoor.SF_OUTSIDE_FACTORY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_FACTORY_RC_CAR.value, AEDoor.SF_RC_CAR_FACTORY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_FACTORY_WHEEL_BOTTOM.value, AEDoor.SF_WHEEL_FACTORY_BOTTOM.value,
lambda state: True)
connect_regions(self, AEDoor.SF_FACTORY_WHEEL_TOP.value, AEDoor.SF_WHEEL_FACTORY_TOP.value,
lambda state: True)
connect_regions(self, AEDoor.SF_FACTORY_MECH.value, AEDoor.SF_MECH_FACTORY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_RC_CAR_FACTORY.value, AEDoor.SF_FACTORY_RC_CAR.value,
lambda state: True)
connect_regions(self, AEDoor.SF_WHEEL_FACTORY_BOTTOM.value, AEDoor.SF_FACTORY_WHEEL_BOTTOM.value,
lambda state: True)
connect_regions(self, AEDoor.SF_WHEEL_FACTORY_TOP.value, AEDoor.SF_FACTORY_WHEEL_TOP.value,
lambda state: True)
connect_regions(self, AEDoor.SF_MECH_FACTORY.value, AEDoor.SF_FACTORY_MECH.value,
lambda state: True)
connect_regions(self, AEDoor.SF_MECH_LAVA.value, AEDoor.SF_LAVA_MECH.value,
lambda state: True)
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AEDoor.SF_MECH_LAVA.value,
lambda state: True)
connect_regions(self, AEDoor.SF_LAVA_CONVEYOR.value, AEDoor.SF_CONVEYOR_LAVA.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AEDoor.SF_LAVA_CONVEYOR.value,
lambda state: True)
# Specter's Factory Conveyor Room
connect_regions(self, AEDoor.SF_CONVEYOR1_ENTRY.value, AEDoor.SF_CONVEYOR1_EXIT.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR2_ENTRY.value, AEDoor.SF_CONVEYOR1_EXIT.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR3_ENTRY.value, AEDoor.SF_CONVEYOR2_EXIT.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR4_ENTRY.value, AEDoor.SF_CONVEYOR3_EXIT.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR5_ENTRY.value, AEDoor.SF_CONVEYOR4_EXIT.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR6_ENTRY.value, AEDoor.SF_CONVEYOR5_EXIT.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR7_ENTRY.value, AEDoor.SF_CONVEYOR6_EXIT.value,
lambda state: True)
# TV Tower
connect_regions(self, AEDoor.TVT_OUTSIDE_LOBBY.value, AEDoor.TVT_LOBBY_OUTSIDE.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_LOBBY_OUTSIDE.value, AEDoor.TVT_OUTSIDE_LOBBY.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_LOBBY_WATER.value, AEDoor.TVT_WATER_LOBBY.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_LOBBY_TANK.value, AEDoor.TVT_TANK_LOBBY.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_WATER_LOBBY.value, AEDoor.TVT_LOBBY_WATER.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_TANK_LOBBY.value, AEDoor.TVT_LOBBY_TANK.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_TANK_FAN.value, AEDoor.TVT_FAN_TANK.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_TANK_BOSS.value, AEDoor.TVT_BOSS_TANK.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_FAN_TANK.value, AEDoor.TVT_TANK_FAN.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_BOSS_TANK.value, AEDoor.TVT_TANK_BOSS.value,
lambda state: True)
# Monkey Madness
connect_regions(self, AEDoor.MM_SL_HUB_WESTERN.value, AEDoor.MM_WESTERN_SL_HUB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB_COASTER.value, AEDoor.MM_COASTER_ENTRY_SL_HUB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB_CIRCUS.value, AEDoor.MM_CIRCUS_SL_HUB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB_GO_KARZ.value, AEDoor.MM_GO_KARZ_SL_HUB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB_CRATER.value, AEDoor.MM_CRATER_SL_HUB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AEDoor.MM_SL_HUB_WESTERN.value,
lambda state: True)
connect_regions(self, AEDoor.MM_COASTER_ENTRY_SL_HUB.value, AEDoor.MM_SL_HUB_COASTER.value,
lambda state: True)
connect_regions(self, AEDoor.MM_COASTER_ENTRY_COASTER1.value, AEDoor.MM_COASTER1_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CIRCUS_SL_HUB.value, AEDoor.MM_SL_HUB_CIRCUS.value,
lambda state: True)
connect_regions(self, AEDoor.MM_GO_KARZ_SL_HUB.value, AEDoor.MM_SL_HUB_GO_KARZ.value,
lambda state: True)
connect_regions(self, AEDoor.MM_COASTER1_COASTER2.value, AEDoor.MM_COASTER2_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.MM_COASTER2_HAUNTED_HOUSE.value, AEDoor.MM_HAUNTED_HOUSE_DISEMBARK.value,
lambda state: True)
connect_regions(self, AEDoor.MM_HAUNTED_HOUSE_COFFIN.value, AEDoor.MM_COFFIN_HAUNTED_HOUSE.value,
lambda state: True)
connect_regions(self, AEDoor.MM_COFFIN_COASTER_ENTRY.value, AEDoor.MM_COASTER_ENTRY_DISEMBARK.value,
lambda state: True)
connect_regions(self, AEDoor.MM_COFFIN_HAUNTED_HOUSE.value, AEDoor.MM_HAUNTED_HOUSE_COFFIN.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CRATER_SL_HUB.value, AEDoor.MM_SL_HUB_CRATER.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CRATER_OUTSIDE_CASTLE.value, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value,
lambda state: True)
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value, AEDoor.MM_CRATER_OUTSIDE_CASTLE.value,
lambda state: True)
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_SIDE_ENTRY.value, AEDoor.MM_SIDE_ENTRY_OUTSIDE_CASTLE.value,
lambda state: True)
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CASTLE_MAIN.value, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SIDE_ENTRY_OUTSIDE_CASTLE.value, AEDoor.MM_OUTSIDE_CASTLE_SIDE_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AEDoor.MM_OUTSIDE_CASTLE_CASTLE_MAIN.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CASTLE_MAIN_MONKEY_HEAD.value, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CASTLE_MAIN_INSIDE_CLIMB.value, AEDoor.MM_INSIDE_CLIMB_CASTLE_MAIN.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CASTLE_MAIN_SPECTER1.value, AEDoor.MM_SPECTER1_ROOM.value,
lambda state: True)
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AEDoor.MM_CASTLE_MAIN_MONKEY_HEAD.value,
lambda state: True)
connect_regions(self, AEDoor.MM_INSIDE_CLIMB_CASTLE_MAIN.value, AEDoor.MM_CASTLE_MAIN_INSIDE_CLIMB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_INSIDE_CLIMB_OUTSIDE_CLIMB.value, AEDoor.MM_OUTSIDE_CLIMB_INSIDE_CLIMB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_OUTSIDE_CLIMB_INSIDE_CLIMB.value, AEDoor.MM_INSIDE_CLIMB_OUTSIDE_CLIMB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_OUTSIDE_CLIMB_CASTLE_MAIN.value, AEDoor.MM_CASTLE_MAIN_FROM_OUTSIDE.value,
lambda state: True)
# A transition is defined as navigating between two doors in the same room.
def set_transitions(self, logic):
# I'm not sure if these have to be manually connected in both directions? I think they do because connections are asymmetric.
# Time Station
connect_regions(self, AEDoor.TIME_ENTRY.value, AEDoor.TIME_MAIN_TRAINING.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_ENTRY.value, AEDoor.TIME_MAIN_MINIGAME.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_MAIN_TRAINING.value, AEDoor.TIME_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_MAIN_MINIGAME.value, AEDoor.TIME_ENTRY.value,
lambda state: True)
# Fossil Field (level contains a single room)
# Primordial Ooze (level contains a single room)
# Molten Lava
connect_regions(self, AEDoor.ML_ENTRY.value, AEDoor.ML_ENTRY_VOLCANO.value,
lambda state: True)
connect_regions(self, AEDoor.ML_ENTRY.value, AEDoor.ML_ENTRY_TRICERATOPS.value,
lambda state: True)
connect_regions(self, AEDoor.ML_ENTRY_VOLCANO.value, AEDoor.ML_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.ML_ENTRY_TRICERATOPS.value, AEDoor.ML_ENTRY.value,
lambda state: True)
# Thick Jungle
# Entry Room
connect_regions(self, AEDoor.TJ_ENTRY.value, AEDoor.TJ_ENTRY_MUSHROOM.value,
lambda state: True)
if logic == "normal":
connect_regions(self, AEDoor.TJ_ENTRY.value, AEDoor.TJ_ENTRY_BOULDER.value,
lambda state: CanSwim(state, self))
else:
connect_regions(self, AEDoor.TJ_ENTRY.value, AEDoor.TJ_ENTRY_BOULDER.value,
lambda state: CanSwim(state, self) or HasFlyer(state, self))
if logic == "normal":
connect_regions(self, AEDoor.TJ_ENTRY.value, AEDoor.TJ_ENTRY_FISH.value,
lambda state: CanSwim(state, self))
else:
connect_regions(self, AEDoor.TJ_ENTRY.value, AEDoor.TJ_ENTRY_FISH.value,
lambda state: CanSwim(state, self) or HasFlyer(state, self))
connect_regions(self, AEDoor.TJ_ENTRY_MUSHROOM.value, AEDoor.TJ_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_ENTRY_BOULDER.value, AEDoor.TJ_ENTRY.value,
lambda state: CanDive(state, self))
connect_regions(self, AEDoor.TJ_ENTRY_FISH.value, AEDoor.TJ_ENTRY.value,
lambda state: CanSwim(state, self))
# Mushroom Room
if logic == "normal":
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AEDoor.TJ_MUSHROOMMAIN.value,
lambda state: HasFlyer(state, self) and CanHitWheel(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AEDoor.TJ_MUSHROOMMAIN.value,
lambda state: (IJ(state, self) or HasHoop(state, self) or (HasFlyer(state, self) and CanHitWheel(state, self))))
else:
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AEDoor.TJ_MUSHROOMMAIN.value,
lambda state: IJ(state, self) or HasHoop(state, self) or HasFlyer(state, self))
# Fish Room
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.TJ_FISH_ENTRY.value, AEDoor.TJ_FISHBOAT.value,
lambda state: CanSwim(state, self) or HasFlyer(state, self))
else:
connect_regions(self, AEDoor.TJ_FISH_ENTRY.value, AEDoor.TJ_FISHBOAT.value,
lambda state: CanSwim(state, self) or IJ(state, self) or HasHoop(state, self) or HasFlyer(state, self))
if logic == "normal":
connect_regions(self, AEDoor.TJ_FISH_TENT.value, AEDoor.TJ_FISHBOAT.value,
lambda state: CanHitWheel(state, self) and CanSwim(state, self))
else:
connect_regions(self, AEDoor.TJ_FISH_TENT.value, AEDoor.TJ_FISHBOAT.value,
lambda state: (CanHitWheel(state, self) or SuperFlyer(state, self, AEDoor.TJ_FISH_TENT.value)) and CanSwim(state, self))
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AEDoor.TJ_FISH_ENTRY.value,
lambda state: True)
if logic == "normal":
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AEDoor.TJ_FISH_TENT.value,
lambda state: HasSling(state, self) or HasPunch(state, self) or (CanSwim(state, self) and CanHitMultiple(state, self)))
else:
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AEDoor.TJ_FISH_TENT.value,
lambda state: HasSling(state, self) or HasPunch(state, self) or (CanSwim(state, self) and CanHitMultiple(state, self)) or SuperFlyer(state, self, AEDoor.TJ_FISHBOAT.value))
# Tent/Vine Room
connect_regions(self, AEDoor.TJ_TENT_FISH.value, AEDoor.TJ_TENT_BOULDER.value,
lambda state: True)
if logic == "normal":
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AEDoor.TJ_TENT_FISH.value,
lambda state: CanSwim(state, self) or HasFlyer(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AEDoor.TJ_TENT_FISH.value,
lambda state: CanSwim(state, self) or HasHoop(state, self) or HasFlyer(state, self))
else:
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AEDoor.TJ_TENT_FISH.value,
lambda state: CanSwim(state, self) or IJ(state, self) or HasHoop(state, self) or HasFlyer(state, self))
# Boulder Room
if logic == "normal":
connect_regions(self, AEDoor.TJ_BOULDER_ENTRY.value, AEDoor.TJ_BOULDER_TENT.value,
lambda state: CanSwim(state, self) and (HasFlyer(state, self) or IJ(state, self)))
else:
connect_regions(self, AEDoor.TJ_BOULDER_ENTRY.value, AEDoor.TJ_BOULDER_TENT.value,
lambda state: CanSwim(state, self))
if logic == "normal":
connect_regions(self, AEDoor.TJ_BOULDER_TENT.value, AEDoor.TJ_BOULDER_ENTRY.value,
lambda state: CanSwim(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.TJ_BOULDER_TENT.value, AEDoor.TJ_BOULDER_ENTRY.value,
lambda state: CanSwim(state, self) or ((IJ(state, self) or HasHoop(state, self)) and HasFlyer(state, self)))
else:
connect_regions(self, AEDoor.TJ_BOULDER_TENT.value, AEDoor.TJ_BOULDER_ENTRY.value,
lambda state: CanSwim(state, self) or HasFlyer(state, self))
# Dark Ruins
# Outside
if logic == "normal":
connect_regions(self, AEDoor.DR_ENTRY.value, AEDoor.DR_OUTSIDE_FENCE.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.DR_ENTRY.value, AEDoor.DR_OUTSIDE_FENCE.value,
lambda state: HasFlyer(state, self) or HasHoop(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.DR_ENTRY.value, AEDoor.DR_OUTSIDE_FENCE.value,
lambda state: True)
connect_regions(self, AEDoor.DR_ENTRY.value, AEDoor.DR_OUTSIDE_HOLE.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.DR_ENTRY.value, AEDoor.DR_OUTSIDE_OBELISK_BOTTOM.value,
lambda state: True)
connect_regions(self, AEDoor.DR_ENTRY.value, AEDoor.DR_OUTSIDE_OBELISK_TOP.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.DR_ENTRY.value, AEDoor.DR_OUTSIDE_WATER_BUTTON.value,
lambda state: CanHitOnce(state, self))
if logic == "normal":
connect_regions(self, AEDoor.DR_ENTRY.value, AEDoor.DR_OUTSIDE_WATER_LEDGE.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.DR_ENTRY.value, AEDoor.DR_OUTSIDE_WATER_LEDGE.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.DR_OUTSIDE_FENCE.value, AEDoor.DR_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_HOLE.value, AEDoor.DR_ENTRY.value,
lambda state: state.has("DR-Block", self.player, 1))
connect_regions(self, AEDoor.DR_OUTSIDE_OBELISK_BOTTOM.value, AEDoor.DR_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_OBELISK_TOP.value, AEDoor.DR_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_WATER_BUTTON.value, AEDoor.DR_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_WATER_LEDGE.value, AEDoor.DR_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_OBELISK_TOP.value, AEDoor.DR_OUTSIDE_HOLE.value,
lambda state: True)
# Fan Basement
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_FENCE.value, AEDoor.DR_FAN_OUTSIDE_HOLE.value,
lambda state: True)
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_HOLE.value, AEDoor.DR_FAN_OUTSIDE_FENCE.value,
lambda state: True)
# Obelisk
connect_regions(self, AEDoor.DR_OBELISK_BOTTOM.value, AEDoor.DR_OBELISK_TOP.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OBELISK_TOP.value, AEDoor.DR_OBELISK_BOTTOM.value,
lambda state: True)
# Water Basement
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AEDoor.DR_WATER_LEDGE.value,
lambda state: True)
connect_regions(self, AEDoor.DR_WATER_LEDGE.value, AEDoor.DR_WATER_SIDE.value,
lambda state: True)
# Cryptic Relics
# Entry Area
connect_regions(self, AEDoor.CR_ENTRY.value, AEDoor.CR_ENTRYOBA.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.CR_ENTRY_SIDE_ROOM.value, AEDoor.CR_ENTRYOBA.value,
lambda state: True)
connect_regions(self, AEDoor.CR_ENTRY_MAIN_RUINS.value, AEDoor.CR_ENTRYOBA.value,
lambda state: True)
connect_regions(self, AEDoor.CR_ENTRYOBA.value, AEDoor.CR_ENTRY_SIDE_ROOM.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.CR_ENTRYOBA.value, AEDoor.CR_ENTRY_MAIN_RUINS.value,
lambda state: CanHitOnce(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CR_ENTRYOBA.value, AEDoor.CR_ENTRY.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.CR_ENTRYOBA.value, AEDoor.CR_ENTRY.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
# Relics
connect_regions(self, AEDoor.CR_MAIN_RUINS_ENTRY.value, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value,
lambda state: HasSling(state, self) or HasPunch(state, self))
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AEDoor.CR_MAIN_RUINS_ENTRY.value,
lambda state: CanHitOnce(state, self))
# Stadium Attack (level contains a single room)
# Crabby Beach
connect_regions(self, AEDoor.CB_ENTRY.value, AEDoor.CB_ENTRY_SECOND_ROOM.value,
lambda state: CB_Lamp(state, self))
connect_regions(self, AEDoor.CB_ENTRY_SECOND_ROOM.value, AEDoor.CB_ENTRY.value,
lambda state: True)
# Coral Cave
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AEDoor.CCAVE_ENTRY_SECOND_ROOM.value,
lambda state: CanSwim(state, self))
else:
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AEDoor.CCAVE_ENTRY_SECOND_ROOM.value,
lambda state: CanSwim(state, self) or IJ(state, self) or (HasHoop(state, self) and SuperFlyer(state, self, AEDoor.CCAVE_ENTRY.value)))
connect_regions(self, AEDoor.CCAVE_ENTRY_SECOND_ROOM.value, AEDoor.CCAVE_ENTRY.value,
lambda state: CanDive(state, self))
# Dexter's Island
# Outside
connect_regions(self, AEDoor.DI_ENTRY.value, AEDoor.DI_ENTRY_STOMACH.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.DI_ENTRY_STOMACH.value, AEDoor.DI_ENTRY.value,
lambda state: True)
# Stomach
connect_regions(self, AEDoor.DI_STOMACH_ENTRY.value, AEDoor.DI_STOMACH_SLIDE_ROOM.value,
lambda state: True)
connect_regions(self, AEDoor.DI_STOMACH_SLIDE_ROOM.value, AEDoor.DI_STOMACH_ENTRY.value,
lambda state: True)
# Slide
if logic == "normal":
connect_regions(self, AEDoor.DI_SLIDE_ROOM_STOMACH.value, AEDoor.DI_SLIDE_ROOM_GALLERY_WATER.value,
lambda state: CanSwim(state, self) and CanHitMultiple(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.DI_SLIDE_ROOM_STOMACH.value, AEDoor.DI_SLIDE_ROOM_GALLERY_WATER.value,
lambda state: CanHitMultiple(state, self))
else:
connect_regions(self, AEDoor.DI_SLIDE_ROOM_STOMACH.value, AEDoor.DI_SLIDE_ROOM_GALLERY_WATER.value,
lambda state: CanHitOnce(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.DI_SLIDE_ROOM_STOMACH.value, AEDoor.DI_SLIDE_ROOM_GALLERY.value,
lambda state: state.has("DI-Button", self.player, 1) and CanHitOnce(state, self))
else:
connect_regions(self, AEDoor.DI_SLIDE_ROOM_STOMACH.value, AEDoor.DI_SLIDE_ROOM_GALLERY.value,
lambda state: (state.has("DI-Button", self.player, 1) and CanHitOnce(state, self)) or IJ(state, self))
if logic == "expert": # This connection is only valid on expert difficulty.
connect_regions(self, AEDoor.DI_SLIDE_ROOM_GALLERY_WATER.value, AEDoor.DI_SLIDE_ROOM_STOMACH.value,
lambda state: IJ(state, self))
connect_regions(self, AEDoor.DI_SLIDE_ROOM_GALLERY.value, AEDoor.DI_SLIDE_ROOM_STOMACH.value,
lambda state: CanHitOnce(state, self))
# Gallery
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ELEVATOR.value, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value,
lambda state: CanDive(state, self))
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value, AEDoor.DI_GALLERY_SLIDE_ELEVATOR.value,
lambda state: CanDive(state, self))
if logic == "normal":
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value, AEDoor.DI_GALLERYBOULDER.value,
lambda state: HasHoop(state, self) or HasRC(state, self))
else:
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value, AEDoor.DI_GALLERYBOULDER.value,
lambda state: HasHoop(state, self) or HasRC(state, self) or IJ(state, self) or HasFlyer(state, self))
connect_regions(self, AEDoor.DI_GALLERYBOULDER.value, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value,
lambda state: True)
connect_regions(self, AEDoor.DI_GALLERYBOULDER.value, AEDoor.DI_GALLERY_TENTACLE.value,
lambda state: DI_Lamp(state, self))
connect_regions(self, AEDoor.DI_GALLERY_TENTACLE.value, AEDoor.DI_GALLERYBOULDER.value,
lambda state: DI_Lamp(state, self))
# Snowy Mammoth (level contains a single room)
# Frosty Retreat
# Outside
if logic == "normal":
connect_regions(self, AEDoor.FR_ENTRY.value, AEDoor.FR_ENTRY_CAVERNS.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.FR_ENTRY.value, AEDoor.FR_ENTRY_CAVERNS.value,
lambda state: True)
# Caverns
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.FR_CAVERNS_ENTRY.value, AEDoor.FR_CAVERNS_WATER.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.FR_CAVERNS_ENTRY.value, AEDoor.FR_CAVERNS_WATER.value,
lambda state: True)
connect_regions(self, AEDoor.FR_CAVERNS_WATER.value, AEDoor.FR_CAVERNS_ENTRY.value,
lambda state: True)
# Hot Springs
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.HS_ENTRY.value, AEDoor.HS_ENTRY_HOT_SPRING.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.HS_ENTRY.value, AEDoor.HS_ENTRY_HOT_SPRING.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.HS_ENTRY.value, AEDoor.HS_ENTRY_POLAR_BEAR_CAVE.value,
lambda state: True)
connect_regions(self, AEDoor.HS_ENTRY_HOT_SPRING.value, AEDoor.HS_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.HS_ENTRY_POLAR_BEAR_CAVE.value, AEDoor.HS_ENTRY.value,
lambda state: True)
# Gladiator Attack (level contains a single room)
# Sushi Temple
connect_regions(self, AEDoor.ST_ENTRY.value, AEDoor.ST_ENTRY_TEMPLE.value,
lambda state: True)
connect_regions(self, AEDoor.ST_ENTRY.value, AEDoor.ST_ENTRY_WELL.value,
lambda state: True)
connect_regions(self, AEDoor.ST_ENTRY_TEMPLE.value, AEDoor.ST_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.ST_ENTRY_WELL.value, AEDoor.ST_ENTRY.value,
lambda state: True)
# Wabi Sabi Wall
# Entry
connect_regions(self, AEDoor.WSW_ENTRY.value, AEDoor.WSW_ENTRY_GONG.value,
lambda state: True)
# Gong Room
if logic == "normal":
connect_regions(self, AEDoor.WSW_GONG_ENTRY.value, AEDoor.WSW_GONG_MIDDLE.value,
lambda state: HasNet(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.WSW_GONG_ENTRY.value, AEDoor.WSW_GONG_MIDDLE.value,
lambda state: HasNet(state, self) or IJ(state, self) or HasFlyer(state, self))
connect_regions(self, AEDoor.WSW_GONG_MIDDLE.value, AEDoor.WSW_GONG_ENTRY.value,
lambda state: True)
# Middle
if logic == "normal":
connect_regions(self, AEDoor.WSW_MIDDLE_GONG.value, AEDoor.WSW_MIDDLE_OBSTACLE.value,
lambda state: HasSling(state, self) or HasFlyer(state, self))
else:
connect_regions(self, AEDoor.WSW_MIDDLE_GONG.value, AEDoor.WSW_MIDDLE_OBSTACLE.value,
lambda state: HasSling(state, self) or HasHoop(state, self) or HasFlyer(state, self))
connect_regions(self, AEDoor.WSW_MIDDLE_OBSTACLE.value, AEDoor.WSW_MIDDLE_GONG.value,
lambda state: True)
# Obstacle Course
if logic == "normal":
connect_regions(self, AEDoor.WSW_OBSTACLE_MIDDLE.value, AEDoor.WSW_OBSTACLE_BARREL.value,
lambda state: CanHitWheel(state, self) or HasFlyer(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.WSW_OBSTACLE_MIDDLE.value, AEDoor.WSW_OBSTACLE_BARREL.value,
lambda state: CanHitWheel(state, self) or HasFlyer(state, self) or HasNet(state, self))
else:
connect_regions(self, AEDoor.WSW_OBSTACLE_MIDDLE.value, AEDoor.WSW_OBSTACLE_BARREL.value,
lambda state: True)
connect_regions(self, AEDoor.WSW_OBSTACLE_BARREL.value, AEDoor.WSW_OBSTACLE_MIDDLE.value,
lambda state: True)
# Crumbling Castle
# Outside
connect_regions(self, AEDoor.CC_ENTRY.value, AEDoor.CC_ENTRY_CASTLE.value,
lambda state: True)
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CC_ENTRY.value, AEDoor.CC_ENTRY_BASEMENT.value,
lambda state: CanSwim(state, self))
else:
connect_regions(self, AEDoor.CC_ENTRY.value, AEDoor.CC_ENTRY_BASEMENT.value,
lambda state: CanSwim(state, self) or HasFlyer(state, self))
connect_regions(self, AEDoor.CC_ENTRY.value, AEDoor.CC_ENTRY_BELL.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.CC_ENTRY_CASTLE.value, AEDoor.CC_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.CC_ENTRY_BASEMENT.value, AEDoor.CC_ENTRY.value,
lambda state: CanSwim(state, self))
connect_regions(self, AEDoor.CC_ENTRY_BELL.value, AEDoor.CC_ENTRY.value,
lambda state: True)
# Boss Door - must be able to reach and hit the button in another room.
connect_regions(self, AEDoor.CC_ENTRY_BELL.value, AEDoor.CC_ENTRY_BOSS.value,
lambda state: state.has("CC-Button", self.player, 1) and CanHitOnce(state, self))
# Castle
connect_regions(self, AEDoor.CC_CASTLEMAIN_ENTRY.value, AEDoor.CC_CASTLEMAIN_BELL.value,
lambda state: True)
connect_regions(self, AEDoor.CC_CASTLEMAIN_BELL.value, AEDoor.CC_CASTLEMAIN_ENTRY.value,
lambda state: True)
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CC_CASTLEMAIN_ENTRY.value, AEDoor.CC_CASTLEMAIN_ELEVATOR.value,
lambda state: CRC_Lamp(state, self))
else:
connect_regions(self, AEDoor.CC_CASTLEMAIN_ENTRY.value, AEDoor.CC_CASTLEMAIN_ELEVATOR.value,
lambda state: CRC_Lamp(state, self) or SuperFlyer(state, self, AEDoor.CC_CASTLEMAIN_ENTRY.value) or IJ(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CC_CASTLEMAIN_ELEVATOR.value, AEDoor.CC_CASTLEMAIN_ENTRY.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.CC_CASTLEMAIN_ELEVATOR.value, AEDoor.CC_CASTLEMAIN_ENTRY.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CC_CASTLEMAIN_ENTRY.value, AEDoor.CC_CASTLEMAINTHRONEROOM.value,
lambda state: CRC_Lamp(state, self))
else:
connect_regions(self, AEDoor.CC_CASTLEMAIN_ENTRY.value, AEDoor.CC_CASTLEMAINTHRONEROOM.value,
lambda state: CRC_Lamp(state, self) or IJ(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CC_CASTLEMAIN_ELEVATOR.value, AEDoor.CC_CASTLEMAINTHRONEROOM.value,
lambda state: HasFlyer(state, self) and CRC_Lamp(state, self))
else:
connect_regions(self, AEDoor.CC_CASTLEMAIN_ELEVATOR.value, AEDoor.CC_CASTLEMAINTHRONEROOM.value,
lambda state: (HasFlyer(state, self) and CRC_Lamp(state, self)) or IJ(state, self) or SuperFlyer(state, self, AEDoor.CC_CASTLEMAIN_ELEVATOR.value))
# Bell Tower
connect_regions(self, AEDoor.CC_BELL_CASTLE.value, AEDoor.CC_BELL_ENTRY.value,
lambda state: CanHitWheel(state, self) or HasFlyer(state, self))
connect_regions(self, AEDoor.CC_BELL_ENTRY.value, AEDoor.CC_BELL_CASTLE.value,
lambda state: True)
# Elevator Room
if logic == "normal":
connect_regions(self, AEDoor.CC_ELEVATOR_CASTLEMAIN.value, AEDoor.CC_ELEVATOR_BASEMENT.value,
lambda state: HasClub(state, self) or HasSling(state, self) or HasPunch(state, self))
else:
connect_regions(self, AEDoor.CC_ELEVATOR_CASTLEMAIN.value, AEDoor.CC_ELEVATOR_BASEMENT.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.CC_ELEVATOR_BASEMENT.value, AEDoor.CC_ELEVATOR_CASTLEMAIN.value,
lambda state: True)
# Waterway
if logic == "normal":
connect_regions(self, AEDoor.CC_BASEMENT_ENTRY.value, AEDoor.CC_BASEMENT_ELEVATOR.value,
lambda state: CanSwim(state, self) and HasPunch(state, self))
else:
connect_regions(self, AEDoor.CC_BASEMENT_ENTRY.value, AEDoor.CC_BASEMENT_ELEVATOR.value,
lambda state: CanSwim(state, self) and (HasPunch(state, self) or IJ(state, self) or HasFlyer(state, self)))
if logic == "normal":
connect_regions(self, AEDoor.CC_BASEMENT_BUTTON_DOWN.value, AEDoor.CC_BASEMENT_ELEVATOR.value,
lambda state: CanSwim(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.CC_BASEMENT_BUTTON_DOWN.value, AEDoor.CC_BASEMENT_ELEVATOR.value,
lambda state: CanSwim(state, self) or SuperFlyer(state, self, AEDoor.CC_BASEMENT_BUTTON_DOWN.value))
else:
connect_regions(self, AEDoor.CC_BASEMENT_BUTTON_DOWN.value, AEDoor.CC_BASEMENT_ELEVATOR.value,
lambda state: CanSwim(state, self) or SuperFlyer(state, self, AEDoor.CC_BASEMENT_BUTTON_DOWN.value) or IJ(state, self))
connect_regions(self, AEDoor.CC_BASEMENT_BUTTON_UP.value, AEDoor.CC_BASEMENT_ELEVATOR.value,
lambda state: True)
if logic == "normal":
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AEDoor.CC_BASEMENT_ENTRY.value,
lambda state: CanHitOnce(state, self) and (CanSwim(state, self) or HasFlyer(state, self)))
elif logic == "hard":
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AEDoor.CC_BASEMENT_ENTRY.value,
lambda state: CanHitOnce(state, self) and (CanSwim(state, self) or IJ(state, self) or HasHoop(state, self) or HasFlyer(state, self)))
else:
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AEDoor.CC_BASEMENT_ENTRY.value,
lambda state: CanHitOnce(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AEDoor.CC_BASEMENT_BUTTON_DOWN.value,
lambda state: CanSwim(state, self))
else:
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AEDoor.CC_BASEMENT_BUTTON_DOWN.value,
lambda state: CanSwim(state, self) or IJ(state, self) or HasFlyer(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AEDoor.CC_BASEMENT_BUTTON_UP.value,
lambda state: IJ(state, self))
else:
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AEDoor.CC_BASEMENT_BUTTON_UP.value,
lambda state: IJ(state, self) or HasFlyer(state, self))
# Button Room
connect_regions(self, AEDoor.CC_BUTTON_BASEMENT_WATER.value, AEDoor.CC_BUTTON_BASEMENT_LEDGE.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BUTTON_BASEMENT_LEDGE.value, AEDoor.CC_BUTTON_BASEMENT_WATER.value,
lambda state: True)
# City Park
# Outside
connect_regions(self, AEDoor.CP_ENTRY.value, AEDoor.CP_OUTSIDE_SEWERS_FRONT.value,
lambda state: CP_Lamp(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CP_ENTRY.value, AEDoor.CP_OUTSIDE_BARREL.value,
lambda state: IJ(state, self) and CanDive(state, self))
else:
connect_regions(self, AEDoor.CP_ENTRY.value, AEDoor.CP_OUTSIDE_BARREL.value,
lambda state: (IJ(state, self) or HasFlyer(state, self)) and CanDive(state, self))
connect_regions(self, AEDoor.CP_OUTSIDE_SEWERS_FRONT.value, AEDoor.CP_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.CP_OUTSIDE_BARREL.value, AEDoor.CP_ENTRY.value,
lambda state: CanDive(state, self))
# Front Sewer
if logic == "normal":
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AEDoor.CP_SEWERSFRONT_BARREL.value,
lambda state: HasRC(state, self) and (CanSwim(state, self) or HasFlyer(state, self)))
elif logic == "hard":
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AEDoor.CP_SEWERSFRONT_BARREL.value,
lambda state: (HasRC(state, self) or IJ(state, self)) and (CanSwim(state, self) or HasFlyer(state, self) or HasHoop(state, self)))
else:
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AEDoor.CP_SEWERSFRONT_BARREL.value,
lambda state: (HasRC(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value)) and (CanSwim(state, self) or HasFlyer(state, self) or HasHoop(state, self)))
if logic == "normal":
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AEDoor.CP_SEWERSFRONT_OUTSIDE.value,
lambda state: HasRC(state, self) and (CanSwim(state, self) or HasFlyer(state, self)))
elif logic == "hard":
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AEDoor.CP_SEWERSFRONT_OUTSIDE.value,
lambda state: HasRC(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AEDoor.CP_SEWERSFRONT_OUTSIDE.value,
lambda state: HasRC(state, self) or IJ(state, self) or (HasHoop(state, self) and HasFlyer(state, self)))
# Back Sewer
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CP_BARREL_SEWERS_FRONT.value, AEDoor.CP_BARRELSEWERMIDDLE.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.CP_BARREL_SEWERS_FRONT.value, AEDoor.CP_BARRELSEWERMIDDLE.value,
lambda state: True)
connect_regions(self, AEDoor.CP_BARREL_OUTSIDE.value, AEDoor.CP_BARRELSEWERMIDDLE.value,
lambda state: CanDive(state, self))
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AEDoor.CP_BARREL_SEWERS_FRONT.value,
lambda state: True)
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AEDoor.CP_BARREL_OUTSIDE.value,
lambda state: CanDive(state, self))
# Specter's Factory
# Outside
connect_regions(self, AEDoor.SF_ENTRY.value, AEDoor.SF_OUTSIDE_FACTORY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_OUTSIDE_FACTORY.value, AEDoor.SF_ENTRY.value,
lambda state: HasFlyer(state, self) or HasPunch(state, self))
# Main Factory
connect_regions(self, AEDoor.SF_FACTORY_OUTSIDE.value, AEDoor.SF_FACTORY_RC_CAR.value,
lambda state: True)
connect_regions(self, AEDoor.SF_FACTORY_WHEEL_BOTTOM.value, AEDoor.SF_FACTORY_RC_CAR.value,
lambda state: True)
connect_regions(self, AEDoor.SF_FACTORY_RC_CAR.value, AEDoor.SF_FACTORY_OUTSIDE.value,
lambda state: True)
connect_regions(self, AEDoor.SF_FACTORY_RC_CAR.value, AEDoor.SF_FACTORY_WHEEL_BOTTOM.value,
lambda state: SF_Lamp(state, self))
if logic == "normal":
connect_regions(self, AEDoor.SF_FACTORY_RC_CAR.value, AEDoor.SF_FACTORY_WHEEL_TOP.value,
lambda state: IJ(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.SF_FACTORY_RC_CAR.value, AEDoor.SF_FACTORY_WHEEL_TOP.value,
lambda state: (HasHoop(state, self) and HasFlyer(state, self)) or SuperFlyer(state, self, AEDoor.SF_FACTORY_RC_CAR.value) or IJ(state, self))
else:
connect_regions(self, AEDoor.SF_FACTORY_RC_CAR.value, AEDoor.SF_FACTORY_WHEEL_TOP.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.SF_FACTORY_WHEEL_TOP.value, AEDoor.SF_FACTORY_RC_CAR.value,
lambda state: True)
if logic == "normal" or logic == "expert":
connect_regions(self, AEDoor.SF_FACTORY_WHEEL_TOP.value, AEDoor.SF_FACTORY_MECH.value,
lambda state: CanHitWheel(state, self))
else: # This is correct as CanHitWheel includes Flyer only on expert, making hard the unique.
connect_regions(self, AEDoor.SF_FACTORY_WHEEL_TOP.value, AEDoor.SF_FACTORY_MECH.value,
lambda state: CanHitWheel(state, self) or SuperFlyer(state, self, AEDoor.SF_FACTORY_WHEEL_TOP.value))
connect_regions(self, AEDoor.SF_FACTORY_MECH.value, AEDoor.SF_FACTORY_WHEEL_TOP.value,
lambda state: CanHitWheel(state, self))
# Triple Wheel
if logic == "normal":
connect_regions(self, AEDoor.SF_WHEEL_FACTORY_BOTTOM.value, AEDoor.SF_WHEEL_FACTORY_TOP.value,
lambda state: HasClub(state, self) or ((HasSling(state, self) or HasPunch(state, self)) and HasFlyer(state, self)))
elif logic == "hard":
connect_regions(self, AEDoor.SF_WHEEL_FACTORY_BOTTOM.value, AEDoor.SF_WHEEL_FACTORY_TOP.value,
lambda state: HasClub(state, self) or ((HasSling(state, self) or HasPunch(state, self) or HasHoop(state, self)) and HasFlyer(state, self)) or SuperFlyer(state, self, AEDoor.SF_WHEEL_FACTORY_BOTTOM.value))
else:
connect_regions(self, AEDoor.SF_WHEEL_FACTORY_BOTTOM.value, AEDoor.SF_WHEEL_FACTORY_TOP.value,
lambda state: HasClub(state, self) or HasHoop(state, self) or HasFlyer(state, self) or IJ(state, self) or (HasPunch(state, self) and (HasRadar(state, self) or HasSling(state, self) or HasRC(state, self) or HasNet(state, self))))
connect_regions(self, AEDoor.SF_WHEEL_FACTORY_TOP.value, AEDoor.SF_WHEEL_FACTORY_BOTTOM.value,
lambda state: True)
# Mech Room
connect_regions(self, AEDoor.SF_MECH_FACTORY.value, AEDoor.SF_MECH_LAVA.value,
lambda state: True)
connect_regions(self, AEDoor.SF_MECH_LAVA.value, AEDoor.SF_MECH_FACTORY.value,
lambda state: True)
# Lava Room
if logic == "normal" or logic == "expert":
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AEDoor.SF_LAVA_CONVEYOR.value,
lambda state: CanHitWheel(state, self))
else: # This is correct as CanHitWheel includes Flyer only on expert, making hard the unique.
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AEDoor.SF_LAVA_CONVEYOR.value,
lambda state: CanHitWheel(state, self) or HasFlyer(state, self))
connect_regions(self, AEDoor.SF_LAVA_CONVEYOR.value, AEDoor.SF_LAVA_MECH.value,
lambda state: True)
# Conveyor Room (at least it's all True...)
connect_regions(self, AEDoor.SF_CONVEYOR1_EXIT.value, AEDoor.SF_CONVEYOR_LAVA.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR2_EXIT.value, AEDoor.SF_CONVEYOR_LAVA.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR3_EXIT.value, AEDoor.SF_CONVEYOR_LAVA.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR4_EXIT.value, AEDoor.SF_CONVEYOR_LAVA.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR5_EXIT.value, AEDoor.SF_CONVEYOR_LAVA.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR6_EXIT.value, AEDoor.SF_CONVEYOR_LAVA.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AEDoor.SF_CONVEYOR1_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AEDoor.SF_CONVEYOR2_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AEDoor.SF_CONVEYOR3_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AEDoor.SF_CONVEYOR4_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AEDoor.SF_CONVEYOR5_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AEDoor.SF_CONVEYOR6_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AEDoor.SF_CONVEYOR7_ENTRY.value,
lambda state: True)
# TV Tower
# Outside
connect_regions(self, AEDoor.TVT_ENTRY.value, AEDoor.TVT_OUTSIDE_LOBBY.value,
lambda state: True)
# Lobby
if logic == "normal":
connect_regions(self, AEDoor.TVT_LOBBY_OUTSIDE.value, AEDoor.TVT_LOBBY_WATER.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.TVT_LOBBY_OUTSIDE.value, AEDoor.TVT_LOBBY_WATER.value,
lambda state: HasFlyer(state, self) or HasSling(state, self) or HasClub(state, self))
else:
connect_regions(self, AEDoor.TVT_LOBBY_OUTSIDE.value, AEDoor.TVT_LOBBY_WATER.value,
lambda state: HasFlyer(state, self) or HasSling(state, self) or HasHoop(state, self) or HasClub(state, self))
connect_regions(self, AEDoor.TVT_LOBBY_OUTSIDE.value, AEDoor.TVT_LOBBY_TANK.value,
lambda state: TVT_Lobby_Lamp(state, self))
connect_regions(self, AEDoor.TVT_LOBBY_WATER.value, AEDoor.TVT_LOBBY_OUTSIDE.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.TVT_LOBBY_TANK.value, AEDoor.TVT_LOBBY_OUTSIDE.value,
lambda state: True)
# Tank Room
connect_regions(self, AEDoor.TVT_TANK_LOBBY.value, AEDoor.TVT_TANK_FAN.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_TANK_LOBBY.value, AEDoor.TVT_TANK_BOSS.value,
lambda state: TVT_Tank_Lamp(state, self))
if logic == "normal":
connect_regions(self, AEDoor.TVT_TANK_FAN.value, AEDoor.TVT_TANK_LOBBY.value,
lambda state: HasPunch(state, self))
else:
connect_regions(self, AEDoor.TVT_TANK_FAN.value, AEDoor.TVT_TANK_LOBBY.value,
lambda state: HasPunch(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.TVT_TANK_FAN.value))
connect_regions(self, AEDoor.TVT_TANK_BOSS.value, AEDoor.TVT_TANK_LOBBY.value,
lambda state: True)
# Monkey Madness
# Specter Land
connect_regions(self, AEDoor.MM_SL_HUB.value, AEDoor.MM_SL_HUB_WESTERN.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB.value, AEDoor.MM_SL_HUB_COASTER.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB.value, AEDoor.MM_SL_HUB_CIRCUS.value,
lambda state: True)
# This is not a mistake because the apworld pre-opens the Jake arena as part of handling the Lobby door.
connect_regions(self, AEDoor.MM_SL_HUB.value, AEDoor.MM_SL_HUB_GO_KARZ.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB.value, AEDoor.MM_SL_HUB_CRATER.value,
lambda state: MM_DoubleDoor(state, self))
connect_regions(self, AEDoor.MM_SL_HUB_WESTERN.value, AEDoor.MM_SL_HUB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB_COASTER.value, AEDoor.MM_SL_HUB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB_CIRCUS.value, AEDoor.MM_SL_HUB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB_GO_KARZ.value, AEDoor.MM_SL_HUB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_SL_HUB_CRATER.value, AEDoor.MM_SL_HUB.value,
lambda state: True)
# Coaster (several one-way connections here)
connect_regions(self, AEDoor.MM_COASTER_ENTRY_SL_HUB.value, AEDoor.MM_COASTER_ENTRY_COASTER1.value,
lambda state: True)
connect_regions(self, AEDoor.MM_COASTER1_ENTRY.value, AEDoor.MM_COASTER1_COASTER2.value,
lambda state: True)
connect_regions(self, AEDoor.MM_COASTER2_ENTRY.value, AEDoor.MM_COASTER2_HAUNTED_HOUSE.value,
lambda state: True)
if logic == "normal":
connect_regions(self, AEDoor.MM_HAUNTED_HOUSE_DISEMBARK.value, AEDoor.MM_HAUNTED_HOUSE_COFFIN.value,
lambda state: CanHitMultiple(state, self) or HasHoop(state, self))
else:
connect_regions(self, AEDoor.MM_HAUNTED_HOUSE_DISEMBARK.value, AEDoor.MM_HAUNTED_HOUSE_COFFIN.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.MM_COFFIN_HAUNTED_HOUSE.value, AEDoor.MM_COFFIN_COASTER_ENTRY.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.MM_COASTER_ENTRY_DISEMBARK.value, AEDoor.MM_COASTER_ENTRY_SL_HUB.value,
lambda state: True)
# Crater
connect_regions(self, AEDoor.MM_CRATER_SL_HUB.value, AEDoor.MM_CRATER_OUTSIDE_CASTLE.value,
lambda state: True)
if logic == "normal":
connect_regions(self, AEDoor.MM_CRATER_OUTSIDE_CASTLE.value, AEDoor.MM_CRATER_SL_HUB.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.MM_CRATER_OUTSIDE_CASTLE.value, AEDoor.MM_CRATER_SL_HUB.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
# Castle Outside
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value, AEDoor.MM_OUTSIDE_CASTLE_SIDE_ENTRY.value,
lambda state: True)
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value, AEDoor.MM_OUTSIDE_CASTLE_CASTLE_MAIN.value,
lambda state: MM_Lamp(state, self))
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_SIDE_ENTRY.value, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value,
lambda state: True)
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CASTLE_MAIN.value, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value,
lambda state: True)
# Castle Foyer
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AEDoor.MM_CASTLE_MAIN_MONKEY_HEAD.value,
lambda state: HasHoop(state, self) and HasRC(state, self))
else:
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AEDoor.MM_CASTLE_MAIN_MONKEY_HEAD.value,
lambda state: HasRC(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AEDoor.MM_CASTLE_MAIN_SPECTER1.value,
lambda state: state.has("MM-Painting", self.player, 1))
else:
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AEDoor.MM_CASTLE_MAIN_SPECTER1.value,
lambda state: state.has("MM-Painting", self.player, 1) or IJ(state, self) or SuperFlyer(state, self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value))
connect_regions(self, AEDoor.MM_CASTLE_MAIN_MONKEY_HEAD.value, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value,
lambda state: HasHoop(state, self) or HasRC(state, self))
connect_regions(self, AEDoor.MM_CASTLE_MAIN_MONKEY_HEAD.value, AEDoor.MM_CASTLE_MAIN_INSIDE_CLIMB.value,
lambda state: state.has("MM-Button", self.player, 1) and (CanHitWheel(state, self) or HasFlyer(state, self)))
connect_regions(self, AEDoor.MM_CASTLE_MAIN_INSIDE_CLIMB.value, AEDoor.MM_CASTLE_MAIN_MONKEY_HEAD.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CASTLE_MAIN_FROM_OUTSIDE.value, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value,
lambda state: True)
# Monkey Head + Inside Climb + Outside Climb
connect_regions(self, AEDoor.MM_INSIDE_CLIMB_CASTLE_MAIN.value, AEDoor.MM_INSIDE_CLIMB_OUTSIDE_CLIMB.value,
lambda state: True)
connect_regions(self, AEDoor.MM_INSIDE_CLIMB_OUTSIDE_CLIMB.value, AEDoor.MM_INSIDE_CLIMB_CASTLE_MAIN.value,
lambda state: True)
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.MM_OUTSIDE_CLIMB_INSIDE_CLIMB.value, AEDoor.MM_OUTSIDE_CLIMB_CASTLE_MAIN.value,
lambda state: HasFlyer(state, self) and HasRC(state, self) and HasSling(state, self))
else:
connect_regions(self, AEDoor.MM_OUTSIDE_CLIMB_INSIDE_CLIMB.value, AEDoor.MM_OUTSIDE_CLIMB_CASTLE_MAIN.value,
lambda state: (HasFlyer(state, self) and HasRC(state, self) and HasSling(state, self)) or IJ(state, self))
# A location is always accessed from a transition. The level entrance is a special case of a transition.
def set_locations(self, logic):
# Time Station
if self.options.mailbox == "true" or (self.options.shufflenet == "true" and self.options.coin == "true"):
connect_regions(self, AEDoor.TIME_ENTRY.value, AELocation.Mailbox60.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_ENTRY.value, AELocation.Mailbox61.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_MINIGAME_MAIN.value, AELocation.Mailbox62.value,
lambda state: True)
connect_regions(self, AEDoor.TIME_TRAINING_MAIN.value, AELocation.Mailbox63.value,
lambda state: True)
# Fossil Field
connect_regions(self, AEDoor.FF_ENTRY.value, AELocation.W1L1Noonan.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.FF_ENTRY.value, AELocation.W1L1Jorjy.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.FF_ENTRY.value, AELocation.W1L1Nati.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.FF_ENTRY.value, AELocation.W1L1TrayC.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.FF_ENTRY.value, AELocation.W1L1TrayC.value,
lambda state: HasNet(state, self))
if self.options.coin == "true":
connect_regions(self, AEDoor.FF_ENTRY.value, AELocation.Coin1.value,
lambda state: True)
if self.options.mailbox == "true":
connect_regions(self, AEDoor.FF_ENTRY.value, AELocation.Mailbox1.value,
lambda state: True)
connect_regions(self, AEDoor.FF_ENTRY.value, AELocation.Mailbox2.value,
lambda state: True)
connect_regions(self, AEDoor.FF_ENTRY.value, AELocation.Mailbox3.value,
lambda state: CanHitOnce(state, self))
# Primordial Ooze
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.W1L2Shay.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.W1L2DrMonk.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.W1L2Ahchoo.value,
lambda state: HasNet(state, self) or HasWaterNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.W1L2Grunt.value,
lambda state: (CanSwim(state, self) or HasFlyer(state, self)) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.W1L2Grunt.value,
lambda state: (CanSwim(state, self) or HasHoop(state, self) or HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.W1L2Grunt.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.W1L2Tyrone.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.W1L2Gornif.value,
lambda state: CanSwim(state, self) and (HasNet(state, self) or HasWaterNet(state, self)))
else:
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.W1L2Gornif.value,
lambda state: HasNet(state, self) or HasWaterNet(state, self))
if self.options.coin == "true":
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.Coin2.value,
lambda state: CanDive(state, self))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.Mailbox4.value,
lambda state: True)
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.Mailbox5.value,
lambda state: True)
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.Mailbox6.value,
lambda state: True)
connect_regions(self, AEDoor.PO_ENTRY.value, AELocation.Mailbox7.value,
lambda state: True)
# Molten Lava
# Outside
connect_regions(self, AEDoor.ML_ENTRY.value, AELocation.W1L3Scotty.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.ML_ENTRY.value, AELocation.W1L3Coco.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.ML_ENTRY.value, AELocation.W1L3JThomas.value,
lambda state: (HasClub(state, self) or HasPunch(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.ML_ENTRY.value, AELocation.W1L3JThomas.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
connect_regions(self, AEDoor.ML_ENTRY.value, AELocation.W1L3Moggan.value,
lambda state: HasNet(state, self))
# Volcano
connect_regions(self, AEDoor.ML_VOLCANO_ENTRY.value, AELocation.W1L3Barney.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.ML_VOLCANO_ENTRY.value, AELocation.W1L3Mattie.value,
lambda state: HasNet(state, self))
# Triceratops
if logic == "normal":
connect_regions(self, AEDoor.ML_TRICERATOPS_ENTRY.value, AELocation.W1L3Rocky.value,
lambda state: HasSling(state, self) and (HasClub(state, self) or HasPunch(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.ML_TRICERATOPS_ENTRY.value, AELocation.W1L3Rocky.value,
lambda state: HasSling(state, self) and HasNet(state, self))
if self.options.coin == "true":
connect_regions(self, AEDoor.ML_ENTRY.value, AELocation.Coin3.value,
lambda state: True)
if self.options.mailbox == "true":
connect_regions(self, AEDoor.ML_ENTRY.value, AELocation.Mailbox8.value,
lambda state: True)
connect_regions(self, AEDoor.ML_ENTRY.value, AELocation.Mailbox9.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.ML_VOLCANO_ENTRY.value, AELocation.Mailbox10.value,
lambda state: True)
connect_regions(self, AEDoor.ML_TRICERATOPS_ENTRY.value, AELocation.Mailbox11.value,
lambda state: True)
connect_regions(self, AEDoor.ML_TRICERATOPS_ENTRY.value, AELocation.Mailbox12.value,
lambda state: HasSling(state, self))
# Thick Jungle
# Entry
if logic == "normal":
connect_regions(self, AEDoor.TJ_ENTRY.value, AELocation.W2L1Marquez.value,
lambda state: CanHitMultiple(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TJ_ENTRY.value, AELocation.W2L1Marquez.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.TJ_ENTRY.value, AELocation.W2L1Livinston.value,
lambda state: CanHitMultiple(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TJ_ENTRY.value, AELocation.W2L1Livinston.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
connect_regions(self, AEDoor.TJ_ENTRY.value, AELocation.W2L1George.value,
lambda state: HasNet(state, self))
# Mushroom
connect_regions(self, AEDoor.TJ_MUSHROOMMAIN.value, AELocation.W2L1Gonzo.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.TJ_MUSHROOMMAIN.value, AELocation.W2L1Zanzibar.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AELocation.W2L1Alphonse.value,
lambda state: HasFlyer(state, self) and CanHitWheel(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AELocation.W2L1Alphonse.value,
lambda state: (IJ(state, self) or HasHoop(state, self) or (HasFlyer(state, self) and CanHitWheel(state, self))) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AELocation.W2L1Alphonse.value,
lambda state: (IJ(state, self) or HasHoop(state, self) or (HasFlyer(state, self) and (CanHitMultiple(state, self) or HasRC(state, self))) or SuperFlyer(state, self, AEDoor.TJ_MUSHROOM_ENTRY.value)) and HasNet(state, self))
# Fish
if logic == "normal":
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AELocation.W2L1Maki.value,
lambda state: HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AELocation.W2L1Maki.value,
lambda state: (HasSling(state, self) or HasFlyer(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AELocation.W2L1Herb.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.TJ_FISH_TENT.value, AELocation.W2L1Dilweed.value,
lambda state: HasNet(state, self))
# Tent
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AELocation.W2L1Stoddy.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AELocation.W2L1Mitong.value,
lambda state: HasNet(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AELocation.W2L1Nasus.value,
lambda state: (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AELocation.W2L1Nasus.value,
lambda state: CanHitMultiple(state, self) and HasNet(state, self))
# Boulder
if logic == "normal":
connect_regions(self, AEDoor.TJ_BOULDER_ENTRY.value, AELocation.W2L1Elehcim.value,
lambda state: CanSwim(state, self) and HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TJ_BOULDER_ENTRY.value, AELocation.W2L1Elehcim.value,
lambda state: CanSwim(state, self) and HasNet(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.TJ_BOULDER_TENT.value, AELocation.W2L1Elehcim.value,
lambda state: HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TJ_BOULDER_TENT.value, AELocation.W2L1Elehcim.value,
lambda state: (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.TJ_BOULDER_TENT.value, AELocation.W2L1Selur.value,
lambda state: (HasSling(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TJ_BOULDER_TENT.value, AELocation.W2L1Selur.value,
lambda state: (HasClub(state, self) or HasSling(state, self) or HasFlyer(state, self)) and HasNet(state, self))
if self.options.coin == "true":
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.TJ_ENTRY.value, AELocation.Coin6.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.TJ_ENTRY.value, AELocation.Coin6.value,
lambda state: IJ(state, self) or (HasHoop(state, self) and CanSwim(state, self)) or HasFlyer(state, self))
connect_regions(self, AEDoor.TJ_MUSHROOMMAIN.value, AELocation.Coin7.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AELocation.Coin8.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AELocation.Coin9.value,
lambda state: True)
if self.options.mailbox == "true":
connect_regions(self, AEDoor.TJ_ENTRY.value, AELocation.Mailbox13.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_ENTRY.value, AELocation.Mailbox14.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AELocation.Mailbox15.value,
lambda state: CanHitOnce(state, self))
if logic == "normal":
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AELocation.Mailbox16.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.TJ_MUSHROOM_ENTRY.value, AELocation.Mailbox16.value,
lambda state: IJ(state, self) or HasHoop(state, self) or HasFlyer(state, self))
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AELocation.Mailbox17.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AELocation.Mailbox18.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.TJ_FISHBOAT.value, AELocation.Mailbox19.value,
lambda state: True)
connect_regions(self, AEDoor.TJ_TENT_BOULDER.value, AELocation.Mailbox20.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.TJ_BOULDER_TENT.value, AELocation.Mailbox21.value,
lambda state: CanHitOnce(state, self))
# Dark Ruins
# Outside
if logic == "normal":
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.W2L2Kyle.value,
lambda state: HasFlyer(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.W2L2Kyle.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.DR_OUTSIDE_WATER_LEDGE.value, AELocation.W2L2Kyle.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.W2L2Stan.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.W2L2Stan.value,
lambda state: (HasFlyer(state, self) or HasHoop(state, self) or IJ(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.W2L2Stan.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.DR_OUTSIDE_FENCE.value, AELocation.W2L2Stan.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.W2L2Kenny.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.DR_OUTSIDE_OBELISK_TOP.value, AELocation.W2L2Kenny.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.W2L2Cratman.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.W2L2Mooshy.value,
lambda state: HasNet(state, self))
# Fan
if logic == "normal":
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_HOLE.value, AELocation.W2L2Nuzzy.value,
lambda state: (HasSling(state, self) or HasHoop(state, self) or HasPunch(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_HOLE.value, AELocation.W2L2Nuzzy.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_HOLE.value, AELocation.W2L2Mav.value,
lambda state: HasNet(state, self))
# Obelisk
connect_regions(self, AEDoor.DR_OBELISK_BOTTOM.value, AELocation.W2L2Papou.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.DR_OBELISK_BOTTOM.value, AELocation.W2L2Trance.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.DR_OBELISK_BOTTOM.value, AELocation.W2L2Bernt.value,
lambda state: HasSling(state, self) and HasNet(state, self))
# Water
if logic == "normal":
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AELocation.W2L2Runt.value,
lambda state: (HasSling(state, self) or HasRC(state, self) or CanSwim(state, self)) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AELocation.W2L2Runt.value,
lambda state: (HasSling(state, self) or HasHoop(state, self) or HasRC(state, self) or CanSwim(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AELocation.W2L2Runt.value,
lambda state: HasNet(state, self) or ((HasRC(state, self) or CanDive(state, self)) and HasWaterNet(state, self)))
if logic == "normal":
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AELocation.W2L2Hoolah.value,
lambda state: (HasClub(state, self) or HasPunch(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AELocation.W2L2Hoolah.value,
lambda state: (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AELocation.W2L2Chino.value,
lambda state: (HasSling(state, self) or HasRC(state, self) or CanSwim(state, self)) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AELocation.W2L2Chino.value,
lambda state: (HasSling(state, self) or HasHoop(state, self) or HasRC(state, self) or CanSwim(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AELocation.W2L2Chino.value,
lambda state: HasNet(state, self) or ((HasRC(state, self) or CanDive(state, self)) and HasWaterNet(state, self)))
if self.options.coin == "true":
if logic == "normal":
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.Coin11.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.Coin11.value,
lambda state: HasFlyer(state, self) or HasHoop(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.Coin11.value,
lambda state: True)
connect_regions(self, AEDoor.DR_OUTSIDE_FENCE.value, AELocation.Coin11.value,
lambda state: True)
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_HOLE.value, AELocation.Coin12.value,
lambda state: True)
if logic == "normal":
connect_regions(self, AEDoor.DR_OBELISK_BOTTOM.value, AELocation.Coin13.value,
lambda state: HasRC(state, self) or HasPunch(state, self))
else:
connect_regions(self, AEDoor.DR_OBELISK_BOTTOM.value, AELocation.Coin13.value,
lambda state: HasFlyer(state, self) or HasRC(state, self) or HasPunch(state, self))
connect_regions(self, AEDoor.DR_WATER_SIDE.value, AELocation.Coin14.value,
lambda state: CanDive(state, self))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.Mailbox22.value,
lambda state: True)
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.Mailbox23.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.Mailbox24.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.DR_ENTRY.value, AELocation.Mailbox25.value,
lambda state: True)
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_HOLE.value, AELocation.Mailbox26.value,
lambda state: True)
connect_regions(self, AEDoor.DR_FAN_OUTSIDE_HOLE.value, AELocation.Mailbox27.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.DR_OBELISK_BOTTOM.value, AELocation.Mailbox28.value,
lambda state: CanHitOnce(state, self))
# Cryptic Relics
# Entry
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CR_ENTRY.value, AELocation.W2L3Bazzle.value,
lambda state: (HasSling(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CR_ENTRY.value, AELocation.W2L3Bazzle.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CR_ENTRY.value, AELocation.W2L3Freeto.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CR_ENTRYOBA.value, AELocation.W2L3Freeto.value,
lambda state: IJ(state, self) and HasPunch(state, self) and HasNet(state, self))
# Side Room
if logic == "normal":
connect_regions(self, AEDoor.CR_SIDE_ROOM_ENTRY.value, AELocation.W2L3Troopa.value,
lambda state: (HasSling(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CR_SIDE_ROOM_ENTRY.value, AELocation.W2L3Troopa.value,
lambda state: (HasSling(state, self) or HasHoop(state, self) or HasFlyer(state, self)) and HasNet(state, self))
# Main Ruins
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AELocation.W2L3Stymie.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AELocation.W2L3Spanky.value,
lambda state: (CanHitWheel(state, self) or HasFlyer(state, self)) and CanSwim(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AELocation.W2L3Spanky.value,
lambda state: ((CanHitWheel(state, self) and CanSwim(state, self)) or IJ(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AELocation.W2L3Spanky.value,
lambda state: ((CanHitWheel(state, self) and CanSwim(state, self)) or IJ(state, self) or HasHoop(state, self) or HasFlyer(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AELocation.W2L3Jesta.value,
lambda state: ((CanHitWheel(state, self) or (HasFlyer(state, self) and CanSwim(state, self))) and HasNet(state, self)))
# Pillar
if logic == "normal":
connect_regions(self, AEDoor.CR_PILLAR_ROOM_MAIN_RUINS.value, AELocation.W2L3Pally.value,
lambda state: (CanHitMultiple(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CR_PILLAR_ROOM_MAIN_RUINS.value, AELocation.W2L3Pally.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CR_PILLAR_ROOM_MAIN_RUINS.value, AELocation.W2L3Crash.value,
lambda state: HasRC(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CR_PILLAR_ROOM_MAIN_RUINS.value, AELocation.W2L3Crash.value,
lambda state: (HasRC(state, self) or HasSling(state, self) or SuperFlyer(state, self, AEDoor.CR_PILLAR_ROOM_MAIN_RUINS.value)) and HasNet(state, self))
if self.options.coin == "true":
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AELocation.Coin17.value,
lambda state: (CanHitWheel(state, self) and CanSwim(state, self)) or IJ(state, self) or HasFlyer(state, self))
else:
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AELocation.Coin17.value,
lambda state: (CanHitWheel(state, self) and CanSwim(state, self)) or IJ(state, self) or HasFlyer(state, self) or HasHoop(state, self))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.CR_ENTRY.value, AELocation.Mailbox29.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.CR_ENTRY.value, AELocation.Mailbox30.value,
lambda state: True)
connect_regions(self, AEDoor.CR_MAIN_RUINS_ENTRY.value, AELocation.Mailbox31.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.CR_MAIN_RUINS_PILLAR_ROOM.value, AELocation.Mailbox32.value,
lambda state: (CanHitWheel(state, self) or HasFlyer(state, self)) and CanSwim(state, self))
connect_regions(self, AEDoor.CR_PILLAR_ROOM_MAIN_RUINS.value, AELocation.Mailbox33.value,
lambda state: CanHitOnce(state, self))
# Stadium Attack
if self.options.coin == "true":
connect_regions(self, AEDoor.SA_ENTRY.value, AEDoor.SA_COMPLETE.value,
lambda state: CanSwim(state, self))
# Crabby Beach
# First
connect_regions(self, AEDoor.CB_ENTRY.value, AELocation.W4L1CoolBlue.value,
lambda state: HasNet(state, self) or HasWaterNet(state, self))
connect_regions(self, AEDoor.CB_ENTRY.value, AELocation.W4L1Sandy.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CB_ENTRY.value, AELocation.W4L1ShellE.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CB_ENTRY.value, AELocation.W4L1Gidget.value,
lambda state: HasNet(state, self))
# Second
connect_regions(self, AEDoor.CB_SECOND_ROOM_ENTRY.value, AELocation.W4L1Shaka.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CB_SECOND_ROOM_ENTRY.value, AELocation.W4L1Puka.value,
lambda state: (HasFlyer(state, self) or CanHitMultiple(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CB_SECOND_ROOM_ENTRY.value, AELocation.W4L1MaxMahalo.value,
lambda state: HasFlyer(state, self) and HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CB_SECOND_ROOM_ENTRY.value, AELocation.W4L1MaxMahalo.value,
lambda state: (IJ(state, self) or HasHoop(state, self) or HasFlyer(state, self)) and (HasSling(state, self) or HasClub(state, self) or HasPunch(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.CB_SECOND_ROOM_ENTRY.value, AELocation.W4L1Moko.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
if self.options.coin == "true":
connect_regions(self, AEDoor.CB_SECOND_ROOM_ENTRY.value, AELocation.Coin21.value,
lambda state: True)
if self.options.mailbox == "true":
connect_regions(self, AEDoor.CB_ENTRY.value, AELocation.Mailbox34.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.CB_ENTRY.value, AELocation.Mailbox35.value,
lambda state: True)
connect_regions(self, AEDoor.CB_SECOND_ROOM_ENTRY.value, AELocation.Mailbox36.value,
lambda state: CanHitOnce(state, self))
# Coral Cave
# First
if logic == "normal":
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AELocation.W4L2Chip.value,
lambda state: CanSwim(state, self) and HasWaterNet(state, self))
else:
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AELocation.W4L2Chip.value,
lambda state: CanSwim(state, self) and (HasNet(state, self) or HasWaterNet(state, self)))
if logic == "normal":
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AELocation.W4L2Oreo.value,
lambda state: ((((HasHoop(state, self) and CanHitMultiple(state, self)) or HasSling(state, self)) and CanSwim(state, self)) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AELocation.W4L2Oreo.value,
lambda state: (CanSwim(state, self) or HasFlyer(state, self) or HasHoop(state, self) or IJ(state, self)) and (CanHitWheel(state, self) or HasFlyer(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AELocation.W4L2Puddles.value,
lambda state: CanDive(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AELocation.W4L2Puddles.value,
lambda state: (CanDive(state, self) or (CanSwim(state, self) and IJ(state, self)) or SuperFlyer(state, self, AEDoor.CCAVE_ENTRY.value)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AELocation.W4L2Puddles.value,
lambda state: (CanDive(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.CCAVE_ENTRY.value) or (HasHoop(state, self) and HasFlyer(state, self))) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AELocation.W4L2Kalama.value,
lambda state: (((((HasHoop(state, self) and CanHitMultiple(state, self)) or HasSling(state, self)) and CanSwim(state, self)) or HasFlyer(state, self)) and HasNet(state, self)) or HasWaterNet(state, self))
else:
connect_regions(self, AEDoor.CCAVE_ENTRY.value, AELocation.W4L2Kalama.value,
lambda state: ((CanSwim(state, self) or HasFlyer(state, self) or HasHoop(state, self) or IJ(state, self)) and (CanHitWheel(state, self) or HasFlyer(state, self)) and HasNet(state, self)) or HasWaterNet(state, self))
# Second
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.W4L2Iz.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.W4L2BongBong.value,
lambda state: (CanHitMultiple(state, self) or HasHoop(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.W4L2BongBong.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.W4L2Jux.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.W4L2Pickles.value,
lambda state: (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.W4L2Pickles.value,
lambda state: (HasClub(state, self) or HasSling(state, self) or HasRC(state, self) or HasPunch(state, self)) and HasNet(state, self))
if self.options.coin == "true":
if logic == "normal":
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.Coin23.value,
lambda state: CanDive(state, self))
else:
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.Coin23.value,
lambda state: CanDive(state, self) or HasRC(state, self))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.Mailbox37.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.CCAVE_SECOND_ROOM_ENTRY.value, AELocation.Mailbox38.value,
lambda state: CanHitOnce(state, self))
# Dexter's Island
# Outside
connect_regions(self, AEDoor.DI_ENTRY.value, AELocation.W4L3TonTon.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.DI_ENTRY.value, AELocation.W4L3Stuw.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DI_ENTRY.value, AELocation.W4L3Stuw.value,
lambda state: (CanHitOnce(state, self) or CanSwim(state, self)) and HasNet(state, self))
# Stomach
if logic == "normal":
connect_regions(self, AEDoor.DI_STOMACH_ENTRY.value, AELocation.W4L3Mars.value,
lambda state: HasRC(state, self) and (HasNet(state, self) or (CanDive(state, self) and HasWaterNet(state, self))))
else:
connect_regions(self, AEDoor.DI_STOMACH_ENTRY.value, AELocation.W4L3Mars.value,
lambda state: HasRC(state, self) and (HasNet(state, self) or HasWaterNet(state, self)))
connect_regions(self, AEDoor.DI_STOMACH_ENTRY.value, AELocation.W4L3Murky.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.DI_STOMACH_ENTRY.value, AELocation.W4L3Horke.value,
lambda state: (CanSwim(state, self) or HasFlyer(state, self)) and CanHitMultiple(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.DI_STOMACH_ENTRY.value, AELocation.W4L3Horke.value,
lambda state: (CanSwim(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DI_STOMACH_ENTRY.value, AELocation.W4L3Horke.value,
lambda state: (CanSwim(state, self) or IJ(state, self) or HasFlyer(state, self)) and HasNet(state, self))
# Slide
# Gallery
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value, AELocation.W4L3Howeerd.value,
lambda state: HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value, AELocation.W4L3Howeerd.value,
lambda state: (HasSling(state, self) or HasFlyer(state, self)) and HasNet(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value, AELocation.W4L3Robbin.value,
lambda state: HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ROOM_TOP.value, AELocation.W4L3Robbin.value,
lambda state: (HasSling(state, self) or HasFlyer(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.DI_GALLERYBOULDER.value, AELocation.W4L3Jakkee.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.DI_GALLERYBOULDER.value, AELocation.W4L3Frederic.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.DI_GALLERYBOULDER.value, AELocation.W4L3Baba.value,
lambda state: HasNet(state, self))
# Tentacle
connect_regions(self, AEDoor.DI_TENTACLE.value, AELocation.W4L3Quirck.value,
lambda state: CanHitMultiple(state, self) and HasNet(state, self))
if self.options.coin == "true":
if logic == "normal":
connect_regions(self, AEDoor.DI_ENTRY.value, AELocation.Coin24.value,
lambda state: CanHitOnce(state, self))
else:
connect_regions(self, AEDoor.DI_ENTRY.value, AELocation.Coin24.value,
lambda state: CanHitOnce(state, self) or CanSwim(state, self))
connect_regions(self, AEDoor.DI_STOMACH_ENTRY.value, AELocation.Coin25.value,
lambda state: CanDive(state, self))
if logic == "normal":
connect_regions(self, AEDoor.DI_SLIDE_ROOM_STOMACH.value, AELocation.Coin28.value,
lambda state: CanSwim(state, self) and (HasPunch(state, self) or HasNet(state, self)))
else:
connect_regions(self, AEDoor.DI_SLIDE_ROOM_STOMACH.value, AELocation.Coin28.value,
lambda state: HasPunch(state, self) or HasNet(state, self))
if logic == "hard": # This connection does not exist on normal difficulty!
connect_regions(self, AEDoor.DI_SLIDE_ROOM_GALLERY_WATER.value, AELocation.Coin28.value,
lambda state: (HasClub(state, self) or HasPunch(state, self) or IJ(state, self)) and (HasPunch(state, self) or HasNet(state, self)))
elif logic == "expert":
connect_regions(self, AEDoor.DI_SLIDE_ROOM_GALLERY_WATER.value, AELocation.Coin28.value,
lambda state: (HasClub(state, self) or HasPunch(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.DI_SLIDE_ROOM_GALLERY_WATER.value)) and (HasPunch(state, self) or HasNet(state, self)))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.DI_ENTRY.value, AELocation.Mailbox39.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.DI_ENTRY.value, AELocation.Mailbox40.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.DI_SLIDE_ROOM_STOMACH.value, AELocation.Mailbox41.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.DI_GALLERY_SLIDE_ELEVATOR.value, AELocation.Mailbox42.value,
lambda state: CanHitOnce(state, self))
# Snowy Mammoth
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Popcicle.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Iced.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Rickets.value,
lambda state: HasSling(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Rickets.value,
lambda state: (HasSling(state, self) or (HasClub(state, self) and HasFlyer(state, self))) and HasNet(state, self))
else:
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Rickets.value,
lambda state: (HasSling(state, self) or HasPunch(state, self) or (HasClub(state, self) and HasFlyer(state, self))) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Skeens.value,
lambda state: (CanHitMultiple(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Skeens.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Denggoy.value,
lambda state: (CanHitMultiple(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Denggoy.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Chilly.value,
lambda state: (CanHitMultiple(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.W5L1Chilly.value,
lambda state: HasNet(state, self))
if self.options.coin == "true":
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.Coin29.value,
lambda state: True)
if self.options.mailbox == "true":
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.Mailbox43.value,
lambda state: True)
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.Mailbox44.value,
lambda state: CanHitOnce(state, self))
if logic == "normal":
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.Mailbox45.value,
lambda state: CanHitMultiple(state, self) or HasFlyer(state, self))
else:
connect_regions(self, AEDoor.SM_ENTRY.value, AELocation.Mailbox45.value,
lambda state: True)
# Frosty Retreat
# Entry
connect_regions(self, AEDoor.FR_ENTRY_CAVERNS.value, AELocation.W5L2Storm.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.FR_ENTRY_CAVERNS.value, AELocation.W5L2Qube.value,
lambda state: HasNet(state, self))
# Water
if logic == "normal":
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AELocation.W5L2Ranix.value,
lambda state: (CanSwim(state, self) and HasNet(state, self)) or (HasSling(state, self) and CanDive(state, self) and HasWaterNet(state, self)))
elif logic == "hard":
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AELocation.W5L2Ranix.value,
lambda state: (CanSwim(state, self) and HasNet(state, self)) or ((HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)) and CanDive(state, self) and HasWaterNet(state, self)))
else:
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AELocation.W5L2Ranix.value,
lambda state: ((CanSwim(state, self) or IJ(state, self) or (HasSling(state, self) and HasHoop(state, self) and HasFlyer(state, self))) and HasNet(state, self)) or ((HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)) and (HasNet(state, self) or (CanDive(state, self) and HasWaterNet(state, self)))))
if logic == "normal":
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AELocation.W5L2Sharpe.value,
lambda state: (CanSwim(state, self) or HasSling(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AELocation.W5L2Sharpe.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AELocation.W5L2Sticky.value,
lambda state: HasNet(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AELocation.W5L2Droog.value,
lambda state: CanDive(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AELocation.W5L2Droog.value,
lambda state: (CanDive(state, self) or HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
# Caverns
connect_regions(self, AEDoor.FR_CAVERNS_ENTRY.value, AELocation.W5L2Gash.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.FR_CAVERNS_WATER.value, AELocation.W5L2Kundra.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.FR_CAVERNS_WATER.value, AELocation.W5L2Shadow.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.FR_CAVERNS_WATER.value, AELocation.W5L2Shadow.value,
lambda state: HasNet(state, self))
if self.options.coin == "true":
if logic == "normal":
connect_regions(self, AEDoor.FR_ENTRY_CAVERNS.value, AELocation.Coin30.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.FR_ENTRY_CAVERNS.value, AELocation.Coin30.value,
lambda state: True)
connect_regions(self, AEDoor.FR_WATER_CAVERNS.value, AELocation.Coin31.value,
lambda state: CanDive(state, self))
if logic == "normal":
connect_regions(self, AEDoor.FR_CAVERNS_ENTRY.value, AELocation.Coin32.value,
lambda state: CanSwim(state, self) or HasFlyer(state, self))
else:
connect_regions(self, AEDoor.FR_CAVERNS_ENTRY.value, AELocation.Coin32.value,
lambda state: True)
if self.options.mailbox == "true":
connect_regions(self, AEDoor.FR_CAVERNS_ENTRY.value, AELocation.Mailbox46.value,
lambda state: CanHitOnce(state, self))
# Hot Springs
# Entry
connect_regions(self, AEDoor.HS_ENTRY.value, AELocation.W5L3Punky.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.HS_ENTRY.value, AELocation.W5L3Ameego.value,
lambda state: CanDive(state, self) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.HS_ENTRY.value, AELocation.W5L3Yoky.value,
lambda state: HasFlyer(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.HS_ENTRY.value, AELocation.W5L3Yoky.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.HS_ENTRY.value, AELocation.W5L3Jory.value,
lambda state: HasFlyer(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.HS_ENTRY.value, AELocation.W5L3Jory.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.HS_ENTRY_HOT_SPRING.value, AELocation.W5L3Yoky.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.HS_ENTRY_HOT_SPRING.value, AELocation.W5L3Jory.value,
lambda state: HasNet(state, self))
# Onsen
connect_regions(self, AEDoor.HS_HOT_SPRING.value, AELocation.W5L3Crank.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.HS_HOT_SPRING.value, AELocation.W5L3Claxter.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.HS_HOT_SPRING.value, AELocation.W5L3Looza.value,
lambda state: HasNet(state, self))
# Polar Bear
if logic == "normal":
connect_regions(self, AEDoor.HS_POLAR_BEAR_CAVE.value, AELocation.W5L3Roti.value,
lambda state: CanHitMultiple(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.HS_POLAR_BEAR_CAVE.value, AELocation.W5L3Roti.value,
lambda state: (CanHitMultiple(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.HS_POLAR_BEAR_CAVE.value)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.HS_POLAR_BEAR_CAVE.value, AELocation.W5L3Dissa.value,
lambda state: CanHitMultiple(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.HS_POLAR_BEAR_CAVE.value, AELocation.W5L3Dissa.value,
lambda state: (CanHitMultiple(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.HS_POLAR_BEAR_CAVE.value)) and HasNet(state, self))
if self.options.coin == "true":
connect_regions(self, AEDoor.HS_HOT_SPRING.value, AELocation.Coin34.value,
lambda state: True)
if logic == "normal":
connect_regions(self, AEDoor.HS_POLAR_BEAR_CAVE.value, AELocation.Coin35.value,
lambda state: CanHitMultiple(state, self))
else:
connect_regions(self, AEDoor.HS_POLAR_BEAR_CAVE.value, AELocation.Coin35.value,
lambda state: CanHitMultiple(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.HS_POLAR_BEAR_CAVE.value))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.HS_ENTRY.value, AELocation.Mailbox47.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and CanHitOnce(state, self))
connect_regions(self, AEDoor.HS_HOT_SPRING.value, AELocation.Mailbox48.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.HS_POLAR_BEAR_CAVE.value, AELocation.Mailbox49.value,
lambda state: True)
# Gladiator Attack
if self.options.coin == "true":
connect_regions(self, AEDoor.GA_ENTRY.value, AEDoor.GA_COMPLETE.value,
lambda state: HasFlyer(state, self))
# Sushi Temple
# Entry
connect_regions(self, AEDoor.ST_ENTRY.value, AELocation.W7L1Taku.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.ST_ENTRY.value, AELocation.W7L1Rocka.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.ST_ENTRY.value, AELocation.W7L1Maralea.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.ST_ENTRY.value, AELocation.W7L1Wog.value,
lambda state: HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.ST_ENTRY.value, AELocation.W7L1Wog.value,
lambda state: (HasSling(state, self) or HasClub(state, self) or HasFlyer(state, self)) and HasNet(state, self))
# Temple
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.W7L1Mayi.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.W7L1Owyang.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.W7L1Long.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.W7L1Elly.value,
lambda state: HasFlyer(state, self) and (HasHoop(state, self) or HasSling(state, self) or HasRC(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.W7L1Elly.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.W7L1Chunky.value,
lambda state: HasFlyer(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.W7L1Chunky.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
# Well
if logic == "normal":
connect_regions(self, AEDoor.ST_WELL.value, AELocation.W7L1Voti.value,
lambda state: HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.ST_WELL.value, AELocation.W7L1Voti.value,
lambda state: (HasSling(state, self) or (HasHoop(state, self) and HasFlyer(state, self)) or SuperFlyer(state, self, AEDoor.ST_WELL.value)) and HasNet(state, self))
connect_regions(self, AEDoor.ST_WELL.value, AELocation.W7L1QuelTin.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.ST_WELL.value, AELocation.W7L1Phaldo.value,
lambda state: HasNet(state, self))
if self.options.coin == "true":
connect_regions(self, AEDoor.ST_ENTRY.value, AELocation.Coin37.value,
lambda state: True)
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.Coin38.value,
lambda state: True)
if logic == "normal":
connect_regions(self, AEDoor.ST_WELL.value, AELocation.Coin39.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.ST_WELL.value, AELocation.Coin39.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.Mailbox50.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.ST_TEMPLE.value, AELocation.Mailbox51.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.ST_WELL.value, AELocation.Mailbox52.value,
lambda state: CanHitOnce(state, self))
# Wabi Sabi Wall
# Entry
connect_regions(self, AEDoor.WSW_ENTRY_GONG.value, AELocation.W7L2Minky.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.WSW_ENTRY_GONG.value, AELocation.W7L2Zobbro.value,
lambda state: HasNet(state, self))
# Gong
connect_regions(self, AEDoor.WSW_GONG_ENTRY.value, AELocation.W7L2Xeeto.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.WSW_GONG_ENTRY.value, AELocation.W7L2Moops.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.WSW_GONG_ENTRY.value, AELocation.W7L2Zanabi.value,
lambda state: HasNet(state, self))
# Middle
connect_regions(self, AEDoor.WSW_MIDDLE_OBSTACLE.value, AELocation.W7L2Doxs.value,
lambda state: HasNet(state, self))
# Obstacle Course
connect_regions(self, AEDoor.WSW_OBSTACLE_BARREL.value, AELocation.W7L2Buddha.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.WSW_OBSTACLE_MIDDLE.value, AELocation.W7L2Fooey.value,
lambda state: HasRC(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.WSW_OBSTACLE_MIDDLE.value, AELocation.W7L2Fooey.value,
lambda state: (HasSling(state, self) or HasRC(state, self)) and HasNet(state, self))
# Barrel
if logic == "normal":
connect_regions(self, AEDoor.WSW_BARREL_OBSTACLE.value, AELocation.W7L2Kong.value,
lambda state: HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.WSW_BARREL_OBSTACLE.value, AELocation.W7L2Kong.value,
lambda state: (HasSling(state, self) or HasHoop(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.WSW_BARREL_OBSTACLE.value, AELocation.W7L2Phool.value,
lambda state: (HasFlyer(state, self) or HasSling(state, self) or (HasHoop(state, self) and (HasClub(state, self) or HasPunch(state, self)))) and HasNet(state, self))
else:
connect_regions(self, AEDoor.WSW_BARREL_OBSTACLE.value, AELocation.W7L2Phool.value,
lambda state: (HasFlyer(state, self) or HasSling(state, self) or HasHoop(state, self)) and HasNet(state, self))
if self.options.coin == "true":
connect_regions(self, AEDoor.WSW_ENTRY_GONG.value, AELocation.Coin40.value,
lambda state: True)
connect_regions(self, AEDoor.WSW_GONG_ENTRY.value, AELocation.Coin41.value,
lambda state: HasNet(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.WSW_BARREL_OBSTACLE.value, AELocation.Coin44.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.WSW_BARREL_OBSTACLE.value, AELocation.Coin44.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.WSW_GONG_ENTRY.value, AELocation.Mailbox53.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.WSW_MIDDLE_GONG.value, AELocation.Mailbox54.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.WSW_MIDDLE_OBSTACLE.value, AELocation.Mailbox55.value,
lambda state: CanHitOnce(state, self))
connect_regions(self, AEDoor.WSW_OBSTACLE_MIDDLE.value, AELocation.Mailbox56.value,
lambda state: CanHitWheel(state, self) or HasFlyer(state, self))
# Crumbling Castle
# Outside
connect_regions(self, AEDoor.CC_ENTRY.value, AELocation.W7L3Robart.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_ENTRY.value, AELocation.W7L3Igor.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_ENTRY.value, AELocation.W7L3Naners.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_ENTRY_BELL.value, AELocation.W7L3Neeners.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_ENTRY_BELL.value, AELocation.W7L3Charles.value,
lambda state: HasPunch(state, self) and HasNet(state, self))
# Castle
connect_regions(self, AEDoor.CC_CASTLEMAINTHRONEROOM.value, AELocation.W7L3Gustav.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_CASTLEMAINTHRONEROOM.value, AELocation.W7L3Wilhelm.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_CASTLEMAINTHRONEROOM.value, AELocation.W7L3Emmanuel.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_CASTLEMAINTHRONEROOM.value, AELocation.W7L3SirCutty.value,
lambda state: HasNet(state, self))
# Waterway
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AELocation.W7L3Calligan.value,
lambda state: (HasPunch(state, self) or CanDive(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AELocation.W7L3Castalist.value,
lambda state: CanDive(state, self) and HasWaterNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AELocation.W7L3Deveneom.value,
lambda state: HasWaterNet(state, self) or (HasNet(state, self) and CanSwim(state, self)))
elif logic == "hard":
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AELocation.W7L3Deveneom.value,
lambda state: HasWaterNet(state, self) or (HasNet(state, self) and (HasFlyer(state, self) or CanSwim(state, self))))
else:
connect_regions(self, AEDoor.CC_BASEMENT_ELEVATOR.value, AELocation.W7L3Deveneom.value,
lambda state: HasWaterNet(state, self) or (HasNet(state, self) and (HasFlyer(state, self) or IJ(state, self) or CanSwim(state, self))))
connect_regions(self, AEDoor.CC_BASEMENT_BUTTON_DOWN.value, AELocation.W7L3Deveneom.value,
lambda state: (HasNet(state, self) or HasWaterNet(state, self)))
# Button Room
connect_regions(self, AEDoor.CC_BUTTON_BASEMENT_WATER.value, AELocation.W7L3Astur.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_BUTTON_BASEMENT_WATER.value, AELocation.W7L3Kilserack.value,
lambda state: HasNet(state, self) or (HasWaterNet(state, self) and CanDive(state, self)))
# Elevator
connect_regions(self, AEDoor.CC_ELEVATOR_CASTLEMAIN.value, AELocation.W7L3Ringo.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_ELEVATOR_CASTLEMAIN.value, AELocation.W7L3Densil.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CC_ELEVATOR_CASTLEMAIN.value, AELocation.W7L3Figero.value,
lambda state: HasFlyer(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CC_ELEVATOR_CASTLEMAIN.value, AELocation.W7L3Figero.value,
lambda state: HasNet(state, self))
# Bell Tower
connect_regions(self, AEDoor.CC_BELL_ENTRY.value, AELocation.W7L3Fej.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CC_BELL_ENTRY.value, AELocation.W7L3Joey.value,
lambda state: HasFlyer(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.CC_BELL_ENTRY.value, AELocation.W7L3Joey.value,
lambda state: (HasHoop(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CC_BELL_ENTRY.value, AELocation.W7L3Joey.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CC_BELL_CASTLE.value, AELocation.W7L3Donqui.value,
lambda state: HasNet(state, self))
# Boss Room
connect_regions(self, AEDoor.CC_BOSS_ROOM.value, AELocation.Boss73.value,
lambda state: CanHitMultiple(state, self))
if self.options.coin == "true":
connect_regions(self, AEDoor.CC_ENTRY_BELL.value, AELocation.Coin45.value,
lambda state: True)
connect_regions(self, AEDoor.CC_CASTLEMAINTHRONEROOM.value, AELocation.Coin46.value,
lambda state: True)
connect_regions(self, AEDoor.CC_BUTTON_BASEMENT_WATER.value, AELocation.Coin49.value,
lambda state: True)
connect_regions(self, AEDoor.CC_ELEVATOR_CASTLEMAIN.value, AELocation.Coin50.value,
lambda state: True)
if self.options.mailbox == "true":
connect_regions(self, AEDoor.CC_ENTRY.value, AELocation.Mailbox57.value,
lambda state: CanHitOnce(state, self))
# City Park
# Outside
if logic == "normal":
connect_regions(self, AEDoor.CP_ENTRY.value, AELocation.W8L1Kaine.value,
lambda state: HasRC(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CP_ENTRY.value, AELocation.W8L1Kaine.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CP_ENTRY.value, AELocation.W8L1Jaxx.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CP_ENTRY.value, AELocation.W8L1Gehry.value,
lambda state: IJ(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CP_ENTRY.value, AELocation.W8L1Gehry.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.CP_ENTRY.value, AELocation.W8L1Alcatraz.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CP_OUTSIDE_BARREL.value, AELocation.W8L1Gehry.value,
lambda state: CanDive(state, self) and HasNet(state, self))
# Front Sewer
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AELocation.W8L1Tino.value,
lambda state: HasRC(state, self) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AELocation.W8L1QBee.value,
lambda state: HasRC(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AELocation.W8L1QBee.value,
lambda state: (HasRC(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value)) and HasNet(state, self))
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AELocation.W8L1McManic.value,
lambda state: (HasRC(state, self) or HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AELocation.W8L1QBee.value,
lambda state: (CanSwim(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AELocation.W8L1QBee.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AELocation.W8L1McManic.value,
lambda state: (CanSwim(state, self) or HasFlyer(state, self)) and HasRC(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AELocation.W8L1McManic.value,
lambda state: HasRC(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AELocation.W8L1McManic.value,
lambda state: (HasRC(state, self) or IJ(state, self) or (HasHoop(state, self) and HasFlyer(state, self))) and HasNet(state, self))
# Back Sewer
connect_regions(self, AEDoor.CP_BARREL_SEWERS_FRONT.value, AELocation.W8L1Dywan.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.W8L1CKHutch.value,
lambda state: CanDive(state, self) and HasNet(state, self))
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.W8L1Winky.value,
lambda state: HasNet(state, self) or (CanDive(state, self) and HasWaterNet(state, self)))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.W8L1BLuv.value,
lambda state: (CanSwim(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.W8L1BLuv.value,
lambda state: (CanSwim(state, self) or HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.W8L1Camper.value,
lambda state: CanDive(state, self) and (HasWaterNet(state, self) or HasNet(state, self)))
else:
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.W8L1Camper.value,
lambda state: (CanDive(state, self) and (HasWaterNet(state, self) or HasNet(state, self))) or ((IJ(state, self) or SuperFlyer(state, self, AEDoor.CP_BARRELSEWERMIDDLE.value)) and HasRC(state, self) and HasNet(state, self)))
if logic == "normal":
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.W8L1Huener.value,
lambda state: CanSwim(state, self) and HasFlyer(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.W8L1Huener.value,
lambda state: (CanSwim(state, self) or HasHoop(state, self)) and HasFlyer(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.W8L1Huener.value,
lambda state: HasFlyer(state, self) and HasNet(state, self))
if self.options.coin == "true":
if logic == "normal":
connect_regions(self, AEDoor.CP_ENTRY.value, AELocation.Coin53.value,
lambda state: IJ(state, self))
else:
connect_regions(self, AEDoor.CP_ENTRY.value, AELocation.Coin53.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.CP_OUTSIDE_BARREL.value, AELocation.Coin53.value,
lambda state: CanDive(state, self))
if logic == "normal":
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AELocation.Coin54.value,
lambda state: HasRC(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AELocation.Coin54.value,
lambda state: HasRC(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value, AELocation.Coin54.value,
lambda state: HasRC(state, self) or IJ(state, self) or (SuperFlyer(state, self, AEDoor.CP_SEWERSFRONT_OUTSIDE.value)))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AELocation.Coin54.value,
lambda state: HasRC(state, self))
else:
connect_regions(self, AEDoor.CP_SEWERSFRONT_BARREL.value, AELocation.Coin54.value,
lambda state: (HasRC(state, self) or IJ(state, self) or (HasHoop(state, self) and HasFlyer(state, self))))
connect_regions(self, AEDoor.CP_BARRELSEWERMIDDLE.value, AELocation.Coin55.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
# Specter's Factory
# Outside
connect_regions(self, AEDoor.SF_ENTRY.value, AELocation.W8L2BigShow.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.SF_OUTSIDE_FACTORY.value, AELocation.W8L2Dreos.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.SF_OUTSIDE_FACTORY.value, AELocation.W8L2BigShow.value,
lambda state: (HasSling(state, self) or HasPunch(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.SF_OUTSIDE_FACTORY.value, AELocation.W8L2BigShow.value,
lambda state: HasNet(state, self))
# Factory
connect_regions(self, AEDoor.SF_FACTORY_WHEEL_TOP.value, AELocation.W8L2Reznor.value,
lambda state: HasNet(state, self))
# Car Room
if logic == "normal":
connect_regions(self, AEDoor.SF_RC_CAR_FACTORY.value, AELocation.W8L2Urkel.value,
lambda state: (HasRC(state, self) or HasPunch(state, self) or IJ(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.SF_RC_CAR_FACTORY.value, AELocation.W8L2Urkel.value,
lambda state: (HasRC(state, self) or HasPunch(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.SF_RC_CAR_FACTORY.value) or (HasHoop(state, self) and HasFlyer(state, self))) and HasNet(state, self))
# Lava Room
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AELocation.W8L2VanillaS.value,
lambda state: HasPunch(state, self) and HasNet(state, self))
if logic == "normal" or logic == "expert":
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AELocation.W8L2Radd.value,
lambda state: CanHitWheel(state, self) and HasNet(state, self))
else: # This is correct as CanHitWheel includes Flyer only on expert, making hard the unique.
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AELocation.W8L2Radd.value,
lambda state: (CanHitWheel(state, self) or HasFlyer(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AELocation.W8L2Shimbo.value,
lambda state: HasRC(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AELocation.W8L2Shimbo.value,
lambda state: (HasRC(state, self) or HasSling(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AELocation.W8L2Shimbo.value,
lambda state: HasNet(state, self))
# Conveyor Room
if logic == "normal":
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AELocation.W8L2Hurt.value,
lambda state: (HasClub(state, self) or HasPunch(state, self)) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AELocation.W8L2Hurt.value,
lambda state: (HasClub(state, self) or HasPunch(state, self) or HasSling(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AELocation.W8L2Hurt.value,
lambda state: (HasClub(state, self) or HasPunch(state, self) or HasSling(state, self) or HasHoop(state, self) or HasRC(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.SF_CONVEYOR_LAVA.value, AELocation.W8L2String.value,
lambda state: HasNet(state, self))
# Mech Room
if logic == "normal":
connect_regions(self, AEDoor.SF_MECH_FACTORY.value, AELocation.W8L2Khamo.value,
lambda state: (HasClub(state, self) or HasPunch(state, self)) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.SF_MECH_FACTORY.value, AELocation.W8L2Khamo.value,
lambda state: (HasClub(state, self) or HasPunch(state, self) or HasSling(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.SF_MECH_FACTORY.value, AELocation.W8L2Khamo.value,
lambda state: (HasClub(state, self) or HasPunch(state, self) or HasSling(state, self) or HasHoop(state, self) or HasRC(state, self)) and HasNet(state, self))
if self.options.coin == "true":
if logic == "normal":
connect_regions(self, AEDoor.SF_RC_CAR_FACTORY.value, AELocation.Coin58.value,
lambda state: HasRC(state, self) or HasPunch(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.SF_RC_CAR_FACTORY.value, AELocation.Coin58.value,
lambda state: HasRC(state, self) or HasPunch(state, self) or IJ(state, self) or SuperFlyer(state, self, AEDoor.SF_RC_CAR_FACTORY.value) or (HasHoop(state, self) and HasFlyer(state, self)))
if logic == "normal" or logic == "expert": # CanHitWheel includes Flyer on expert.
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AELocation.Coin59.value,
lambda state: CanHitWheel(state, self))
else:
connect_regions(self, AEDoor.SF_LAVA_MECH.value, AELocation.Coin59.value,
lambda state: CanHitWheel(state, self) or HasFlyer(state, self))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.SF_ENTRY.value, AELocation.Mailbox58.value,
lambda state: True)
# TV Tower
# Outside
connect_regions(self, AEDoor.TVT_OUTSIDE_LOBBY.value, AELocation.W8L3Fredo.value,
lambda state: HasPunch(state, self) and HasNet(state, self))
# Basement
if logic == "normal":
connect_regions(self, AEDoor.TVT_WATER_LOBBY.value, AELocation.W8L3Charlee.value,
lambda state: HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TVT_WATER_LOBBY.value, AELocation.W8L3Charlee.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
connect_regions(self, AEDoor.TVT_WATER_LOBBY.value, AELocation.W8L3Mach3.value,
lambda state: HasNet(state, self) or HasWaterNet(state, self))
# Lobby
connect_regions(self, AEDoor.TVT_LOBBY_OUTSIDE.value, AELocation.W8L3Tortuss.value,
lambda state: HasNet(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.TVT_LOBBY_OUTSIDE.value, AELocation.W8L3Manic.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.TVT_LOBBY_OUTSIDE.value, AELocation.W8L3Manic.value,
lambda state: (HasFlyer(state, self) or IJ(state, self) or HasHoop(state, self)) and HasNet(state, self))
# Tank
connect_regions(self, AEDoor.TVT_TANK_LOBBY.value, AELocation.W8L3Ruptdis.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.TVT_TANK_LOBBY.value, AELocation.W8L3Eighty7.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.TVT_TANK_FAN.value, AELocation.W8L3Danio.value,
lambda state: HasNet(state, self))
# Fan
connect_regions(self, AEDoor.TVT_FAN_TANK.value, AELocation.W8L3Roosta.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
connect_regions(self, AEDoor.TVT_FAN_TANK.value, AELocation.W8L3Tellis.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
connect_regions(self, AEDoor.TVT_FAN_TANK.value, AELocation.W8L3Whack.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
connect_regions(self, AEDoor.TVT_FAN_TANK.value, AELocation.W8L3Frostee.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
# Boss
if logic == "normal":
connect_regions(self, AEDoor.TVT_BOSS_TANK.value, AELocation.Boss83.value,
lambda state: HasSling(state, self))
else:
connect_regions(self, AEDoor.TVT_BOSS_TANK.value, AELocation.Boss83.value,
lambda state: HasSling(state, self) or (HasFlyer(state, self) and HasRC(state, self)))
if self.options.coin == "true":
if logic == "normal":
connect_regions(self, AEDoor.TVT_WATER_LOBBY.value, AELocation.Coin64.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
else:
connect_regions(self, AEDoor.TVT_WATER_LOBBY.value, AELocation.Coin64.value,
lambda state: True)
connect_regions(self, AEDoor.TVT_TANK_LOBBY.value, AELocation.Coin66.value,
lambda state: True)
# Monkey Madness
# Coaster (multiple rooms)
connect_regions(self, AEDoor.MM_COASTER_ENTRY_SL_HUB.value, AELocation.W9L1Goopo.value,
lambda state: HasNet(state, self))
# Haunted House
if logic == "normal":
connect_regions(self, AEDoor.MM_HAUNTED_HOUSE_DISEMBARK.value, AELocation.W9L1Porto.value,
lambda state: (CanHitMultiple(state, self) or HasHoop(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_HAUNTED_HOUSE_DISEMBARK.value, AELocation.W9L1Porto.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
# Coffin Room
connect_regions(self, AEDoor.MM_COFFIN_HAUNTED_HOUSE.value, AELocation.W9L1Slam.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.MM_COFFIN_HAUNTED_HOUSE.value, AELocation.W9L1Junk.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.MM_COFFIN_HAUNTED_HOUSE.value, AELocation.W9L1Crib.value,
lambda state: HasNet(state, self))
# Circus
if logic == "normal":
connect_regions(self, AEDoor.MM_CIRCUS_SL_HUB.value, AELocation.W9L1Professor.value,
lambda state: HasFlyer(state, self) and (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)))
elif logic == "hard":
connect_regions(self, AEDoor.MM_CIRCUS_SL_HUB.value, AELocation.W9L1Professor.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)))
else:
connect_regions(self, AEDoor.MM_CIRCUS_SL_HUB.value, AELocation.W9L1Professor.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and (CanHitMultiple(state, self) or HasRC(state, self)))
# Go Karz
if logic == "normal":
connect_regions(self, AEDoor.MM_GO_KARZ_SL_HUB.value, AELocation.W9L1Jake.value,
lambda state: HasClub(state, self) or HasPunch(state, self))
else:
connect_regions(self, AEDoor.MM_GO_KARZ_SL_HUB.value, AELocation.W9L1Jake.value,
lambda state: CanHitMultiple(state, self))
# Western Land
if logic == "normal":
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Nak.value,
lambda state: HasSling(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Nak.value,
lambda state: (HasSling(state, self) or HasHoop(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Nak.value,
lambda state: (HasSling(state, self) or HasHoop(state, self) or HasFlyer(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Cloy.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Shaw.value,
lambda state: HasSling(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Shaw.value,
lambda state: (HasSling(state, self) or HasHoop(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Shaw.value,
lambda state: (HasSling(state, self) or HasHoop(state, self) or HasFlyer(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Flea.value,
lambda state: HasSling(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Flea.value,
lambda state: (HasSling(state, self) or HasHoop(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.W9L1Flea.value,
lambda state: (HasSling(state, self) or HasHoop(state, self) or HasFlyer(state, self)) and HasNet(state, self))
# Crater
if logic == "normal":
connect_regions(self, AEDoor.MM_CRATER_SL_HUB.value, AELocation.W9L1Schafette.value,
lambda state: HasFlyer(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_CRATER_SL_HUB.value, AELocation.W9L1Schafette.value,
lambda state: HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_CRATER_OUTSIDE_CASTLE.value, AELocation.W9L1Schafette.value,
lambda state: HasFlyer(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.MM_CRATER_OUTSIDE_CASTLE.value, AELocation.W9L1Schafette.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_CRATER_OUTSIDE_CASTLE.value, AELocation.W9L1Schafette.value,
lambda state: (HasFlyer(state, self) or IJ(state, self) or HasHoop(state, self)) and HasNet(state, self))
# Castle Outside
if logic == "normal":
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value, AELocation.W9L1Donovan.value,
lambda state: state.has("MM-UFOs", self.player, 1) and HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value, AELocation.W9L1Donovan.value,
lambda state: state.has("MM-UFOs", self.player, 1) and (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value, AELocation.W9L1Laura.value,
lambda state: state.has("MM-UFOs", self.player, 1) and HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value, AELocation.W9L1Laura.value,
lambda state: state.has("MM-UFOs", self.player, 1) and (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)) and HasNet(state, self))
# Castle Foyer
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AELocation.W9L1Uribe.value,
lambda state: HasPunch(state, self) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AELocation.W9L1Gordo.value,
lambda state: HasRC(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AELocation.W9L1Gordo.value,
lambda state: (HasRC(state, self) or HasFlyer(state, self)) and HasNet(state, self))
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AELocation.W9L1Raeski.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AELocation.W9L1Poopie.value,
lambda state: CanHitOnce(state, self) and HasNet(state, self))
# Inside Climb
connect_regions(self, AEDoor.MM_INSIDE_CLIMB_CASTLE_MAIN.value, AELocation.W9L1Teacup.value,
lambda state: HasNet(state, self))
connect_regions(self, AEDoor.MM_INSIDE_CLIMB_CASTLE_MAIN.value, AELocation.W9L1Shine.value,
lambda state: HasNet(state, self))
# Space Climb
connect_regions(self, AEDoor.MM_OUTSIDE_CLIMB_INSIDE_CLIMB.value, AELocation.W9L1Wrench.value,
lambda state: (HasFlyer(state, self) or IJ(state, self)) and HasNet(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.MM_OUTSIDE_CLIMB_INSIDE_CLIMB.value, AELocation.W9L1Bronson.value,
lambda state: HasFlyer(state, self) and HasRC(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_OUTSIDE_CLIMB_INSIDE_CLIMB.value, AELocation.W9L1Bronson.value,
lambda state: ((HasFlyer(state, self) and HasRC(state, self)) or IJ(state, self)) and HasNet(state, self))
# Monkey Head Room
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AELocation.W9L1Bungee.value,
lambda state: (CanHitWheel(state, self) or HasFlyer(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AELocation.W9L1Carro.value,
lambda state: (CanHitWheel(state, self) or HasFlyer(state, self)) and HasRC(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AELocation.W9L1Carro.value,
lambda state: (CanHitWheel(state, self) or HasFlyer(state, self)) and (HasRC(state, self) or HasSling(state, self)) and HasNet(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AELocation.W9L1Carlito.value,
lambda state: HasSling(state, self) and HasFlyer(state, self) and HasNet(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AELocation.W9L1Carlito.value,
lambda state: (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self) or HasFlyer(state, self)) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AELocation.W9L1Carlito.value,
lambda state: (CanHitWheel(state, self) or HasFlyer(state, self)) and HasNet(state, self))
# "Warning" Side Room
if logic == "normal":
connect_regions(self, AEDoor.MM_SIDE_ENTRY_OUTSIDE_CASTLE.value, AELocation.W9L1BG.value,
lambda state: HasSling(state, self) and HasNet(state, self))
else:
connect_regions(self, AEDoor.MM_SIDE_ENTRY_OUTSIDE_CASTLE.value, AELocation.W9L1BG.value,
lambda state: (HasSling(state, self) or HasFlyer(state, self)) and HasNet(state, self))
# Specter 1
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.MM_SPECTER1_ROOM.value, AELocation.Specter.value,
lambda state: (HasClub(state, self) or HasPunch(state, self)) and ((self.options.goal != "mmtoken") or Tokens(state, self, min(self.options.requiredtokens, self.options.totaltokens))))
else:
connect_regions(self, AEDoor.MM_SPECTER1_ROOM.value, AELocation.Specter.value,
lambda state: (HasClub(state, self) or HasSling(state, self) or HasPunch(state, self)) and ((self.options.goal != "mmtoken") or Tokens(state, self, min(self.options.requiredtokens, self.options.totaltokens))))
if self.options.coin == "true":
connect_regions(self, AEDoor.MM_COASTER1_ENTRY.value, AELocation.Coin73.value,
lambda state: True)
connect_regions(self, AEDoor.MM_COASTER2_ENTRY.value, AELocation.Coin74.value,
lambda state: True)
connect_regions(self, AEDoor.MM_HAUNTED_HOUSE_DISEMBARK.value, AELocation.Coin75.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.MM_WESTERN_SL_HUB.value, AELocation.Coin77.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CRATER_OUTSIDE_CASTLE.value, AELocation.Coin78.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
connect_regions(self, AEDoor.MM_OUTSIDE_CASTLE_CRATER.value, AELocation.Coin79.value,
lambda state: True)
connect_regions(self, AEDoor.MM_CASTLE_MAIN_OUTSIDE_CASTLE.value, AELocation.Coin80.value,
lambda state: CanHitOnce(state, self))
if logic == "normal" or logic == "hard":
connect_regions(self, AEDoor.MM_OUTSIDE_CLIMB_INSIDE_CLIMB.value, AELocation.Coin82.value,
lambda state: HasFlyer(state, self) and HasRC(state, self))
else:
connect_regions(self, AEDoor.MM_OUTSIDE_CLIMB_INSIDE_CLIMB.value, AELocation.Coin82.value,
lambda state: (HasFlyer(state, self) and HasRC(state, self)) or IJ(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AELocation.Coin84.value,
lambda state: HasSling(state, self) and HasFlyer(state, self))
elif logic == "hard":
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AELocation.Coin84.value,
lambda state: HasClub(state, self) or HasSling(state, self) or HasPunch(state, self) or HasFlyer(state, self))
else:
connect_regions(self, AEDoor.MM_MONKEY_HEAD_CASTLE_MAIN.value, AELocation.Coin84.value,
lambda state: CanHitWheel(state, self) or HasFlyer(state, self))
if logic == "normal":
connect_regions(self, AEDoor.MM_SIDE_ENTRY_OUTSIDE_CASTLE.value, AELocation.Coin85.value,
lambda state: HasFlyer(state, self))
else:
connect_regions(self, AEDoor.MM_SIDE_ENTRY_OUTSIDE_CASTLE.value, AELocation.Coin85.value,
lambda state: HasFlyer(state, self) or IJ(state, self))
if self.options.mailbox == "true":
connect_regions(self, AEDoor.MM_COASTER_ENTRY_SL_HUB.value, AELocation.Mailbox59.value,
lambda state: True)
# Peak Point Matrix
if self.options.goal != "mm":
connect_regions(self, AEDoor.PPM_ENTRY.value, AELocation.Specter2.value,
lambda state: HasSling(state, self) and (HasClub(state, self) or HasHoop(state, self) or HasPunch(state, self)) and HasNet(state, self))
if self.options.fasttokengoal == self.options.fasttokengoal.option_on:
if self.options.goal == "mmtoken":
connect_regions(self, AEDoor.TIME_TRAINING_WATERNET.value, AEDoor.MM_SPECTER1_ROOM.value,
lambda state: Tokens(state, self,min(self.options.requiredtokens, self.options.totaltokens)))
if self.options.goal == "ppmtoken":
connect_regions(self, AEDoor.TIME_TRAINING_WATERNET.value, AEDoor.PPM_ENTRY.value,
lambda state: Tokens(state, self, min(self.options.requiredtokens, self.options.totaltokens)))
# Item Checking Helper Functions
def Keys(state, world, count):
return state.has(AEItem.Key.value, world.player, count)
def Tokens(state, world, count):
# Check to see if the settings would create tokens at all.
if world.options.goal == "mm" or world.options.goal == "ppm":
return True
return state.has(AEItem.Token.value, world.player, count)
def HasClub(state, world):
return state.has(AEItem.Club.value, world.player, 1)
def HasNet(state, world):
return state.has(AEItem.Net.value, world.player, 1)
def HasRadar(state, world):
return state.has(AEItem.Radar.value, world.player, 1)
def HasSling(state, world):
return state.has(AEItem.Sling.value, world.player, 1)
def HasHoop(state, world):
return state.has(AEItem.Hoop.value, world.player, 1)
def HasFlyer(state, world):
return state.has(AEItem.Flyer.value, world.player, 1)
def HasRC(state, world):
return state.has(AEItem.Car.value, world.player, 1)
def HasPunch(state, world):
return state.has(AEItem.Punch.value, world.player, 1)
def CanSwim(state, world):
return (state.has(AEItem.WaterNet.value, world.player, 1) or state.has(AEItem.ProgWaterNet.value, world.player, 1))
def CanDive(state, world):
return (state.has(AEItem.WaterNet.value, world.player, 1) or state.has(AEItem.ProgWaterNet.value, world.player, 2))
# Logic Helper Functions
def HasWaterNet(state, world): # CanSwim + CanWaterCatch together
return (state.has(AEItem.WaterNet.value, world.player, 1) or (state.has(AEItem.WaterCatch.value, world.player, 1) and state.has(AEItem.ProgWaterNet.value, world.player, 1)))
def CanHitOnce(state, world):
return HasClub(state, world) or HasRadar(state, world) or HasSling(state, world) or HasHoop(state, world) or HasFlyer(state, world) or HasRC(state, world) or HasPunch(state, world)
def CanHitMultiple(state, world):
if world.options.logic == "normal":
return HasClub(state, world) or HasSling(state, world) or HasPunch(state, world)
else:
return HasClub(state, world) or HasSling(state, world) or HasHoop(state, world) or HasPunch(state, world)
def CanHitWheel(state, world):
if world.options.logic == "normal" or world.options.logic == "hard":
return CanHitMultiple(state, world)
else:
return CanHitMultiple(state, world) or HasFlyer(state, world) or HasRC(state, world)
def SuperFlyer(state, world, region) -> bool:
# If the option is off, Super Flyer is not in logic.
if world.options.superflyer == "false":
return False
# If the difficulty is normal, Super Flyer is never in logic.
if world.options.logic == "normal":
return False
# If the player does not have the required gadgets, Super Flyer is unavailable.
if (HasFlyer(state, world) and (HasNet(state, world) or HasClub(state, world) or HasSling(state, world) or HasPunch(state, world))) == False:
return False
# If the player can reach this location without activating the Flyer, Super Flyer is available. To check for this, we check for the ability to access this region on a modified CollectionState. The Radar conveniently has the same ground pound properties as the Flyer while introducing no new access, and so replacing the Flyer with the Radar in this state serves as a valid check.
teststate = state.copy()
teststate.remove(world.create_item(AEItem.Flyer.value))
teststate.collect(world.create_item(AEItem.Radar.value), prevent_sweep = True)
return world.get_region(region).can_reach(teststate)
def IJ(state, world):
return HasSling(state, world) and world.options.infinitejump == "true"
# Lamp and Door Functions
def MM_DoubleDoor(state, world):
return state.has(AEItem.MM_DoubleDoorKey.value, world.player, 1)
def CB_Lamp(state, world):
if state.has(AEItem.CB_Lamp.value, world.player, 1):
return True
return state.has("CB Monkey", world.player, 3) and world.options.lamp == "false"
# locs_to_check = [AELocation.W4L1CoolBlue.value, AELocation.W4L1Sandy.value, AELocation.W4L1ShellE.value, AELocation.W4L1Gidget.value, AELocation.W4L1Shaka.value, AELocation.W4L1MaxMahalo.value, AELocation.W4L1Moko.value, AELocation.W4L1Puka.value]
# locs_accessible = CountAccessibleLocations(state, world, locs_to_check)
# return locs_accessible >= 3
def DI_Lamp(state, world):
if state.has(AEItem.DI_Lamp.value, world.player, 1):
return True
return state.has("DI Monkey", world.player, 5) and world.options.lamp == "false"
# locs_to_check = [AELocation.W4L3Stuw.value, AELocation.W4L3TonTon.value, AELocation.W4L3Murky.value, AELocation.W4L3Howeerd.value, AELocation.W4L3Robbin.value, AELocation.W4L3Jakkee.value, AELocation.W4L3Frederic.value, AELocation.W4L3Baba.value, AELocation.W4L3Mars.value, AELocation.W4L3Horke.value, AELocation.W4L3Quirck.value]
# locs_accessible = CountAccessibleLocations(state, world, locs_to_check)
# return locs_accessible >= 5
def CRC_Lamp(state, world):
if state.has(AEItem.CrC_Lamp.value, world.player, 1):
return True
return state.has("CrC Monkey", world.player, 5) and world.options.lamp == "false"
# locs_to_check = [AELocation.W7L3Naners.value, AELocation.W7L3Robart.value, AELocation.W7L3Neeners.value, AELocation.W7L3Gustav.value, AELocation.W7L3Wilhelm.value, AELocation.W7L3Emmanuel.value, AELocation.W7L3SirCutty.value, AELocation.W7L3Calligan.value, AELocation.W7L3Castalist.value, AELocation.W7L3Deveneom.value, AELocation.W7L3Igor.value, AELocation.W7L3Charles.value, AELocation.W7L3Astur.value, AELocation.W7L3Kilserack.value, AELocation.W7L3Ringo.value, AELocation.W7L3Densil.value, AELocation.W7L3Figero.value, AELocation.W7L3Fej.value, AELocation.W7L3Joey.value, AELocation.W7L3Donqui.value]
# locs_accessible = CountAccessibleLocations(state, world, locs_to_check)
# return locs_accessible >= 5
def CP_Lamp(state, world):
if state.has(AEItem.CP_Lamp.value, world.player, 1):
return True
return state.has("CP Monkey", world.player, 3) and world.options.lamp == "false"
# locs_to_check = [AELocation.W8L1Kaine.value, AELocation.W8L1Jaxx.value, AELocation.W8L1Gehry.value, AELocation.W8L1Alcatraz.value, AELocation.W8L1Tino.value, AELocation.W8L1QBee.value, AELocation.W8L1McManic.value, AELocation.W8L1Dywan.value, AELocation.W8L1CKHutch.value, AELocation.W8L1Winky.value, AELocation.W8L1BLuv.value, AELocation.W8L1Camper.value, AELocation.W8L1Huener.value]
# locs_accessible = CountAccessibleLocations(state, world, locs_to_check)
# return locs_accessible >= 3
def SF_Lamp(state, world):
if state.has(AEItem.SF_Lamp.value, world.player, 1):
return True
return state.has("SF Monkey", world.player, 3) and world.options.lamp == "false"
# locs_to_check = [AELocation.W8L2BigShow.value, AELocation.W8L2Dreos.value, AELocation.W8L2Reznor.value, AELocation.W8L2Urkel.value, AELocation.W8L2VanillaS.value, AELocation.W8L2Radd.value, AELocation.W8L2Shimbo.value, AELocation.W8L2Hurt.value, AELocation.W8L2String.value, AELocation.W8L2Khamo.value]
# locs_accessible = CountAccessibleLocations(state, world, locs_to_check)
# return locs_accessible >= 3
def TVT_Lobby_Lamp(state, world):
if state.has(AEItem.TVT_Lobby_Lamp.value, world.player, 1):
return True
return state.has("TVT Monkey", world.player, 3) and world.options.lamp == "false"
# locs_to_check = [AELocation.W8L3Fredo.value, AELocation.W8L3Charlee.value, AELocation.W8L3Mach3.value, AELocation.W8L3Tortuss.value, AELocation.W8L3Manic.value, AELocation.W8L3Ruptdis.value, AELocation.W8L3Eighty7.value, AELocation.W8L3Danio.value, AELocation.W8L3Roosta.value, AELocation.W8L3Tellis.value, AELocation.W8L3Whack.value, AELocation.W8L3Frostee.value]
# locs_accessible = CountAccessibleLocations(state, world, locs_to_check)
# return locs_accessible >= 3
def TVT_Tank_Lamp(state, world):
if state.has(AEItem.TVT_Tank_Lamp.value, world.player, 1):
return True
return state.has("TVT Monkey", world.player, 6) and world.options.lamp == "false"
# locs_to_check = [AELocation.W8L3Fredo.value, AELocation.W8L3Charlee.value, AELocation.W8L3Mach3.value, AELocation.W8L3Tortuss.value, AELocation.W8L3Manic.value, AELocation.W8L3Ruptdis.value, AELocation.W8L3Eighty7.value, AELocation.W8L3Danio.value, AELocation.W8L3Roosta.value, AELocation.W8L3Tellis.value, AELocation.W8L3Whack.value, AELocation.W8L3Frostee.value]
# locs_accessible = CountAccessibleLocations(state, world, locs_to_check)
# return locs_accessible >= 6
def MM_Lamp(state, world):
if state.has(AEItem.MM_Lamp.value, world.player, 1):
return True
# TODO: check exactly which monkeys apply to this lamp.
return state.has("MM UFO Monkey", world.player, 2) and world.options.lamp == "false"
# locs_to_check = [AELocation.W9L1Donovan.value, AELocation.W9L1Laura.value]
# locs_accessible = CountAccessibleLocations(state, world, locs_to_check)
# return locs_accessible >= 2
def HasAllMonkeys(state, world):
# ''' Event item checking - floods spoiler logs. NOTE: Add "# " to the beginning to uncomment.
return (state.has("FF Monkey", world.player, 4) and state.has("PO Monkey", world.player, 4)
and state.has("ML Monkey", world.player, 7) and state.has("TJ Monkey", world.player, 14)
and state.has("DR Monkey", world.player, 13) and state.has("CR Monkey", world.player, 8)
and state.has("CB Monkey", world.player, 8) and state.has("CoC Monkey", world.player, 8)
and state.has("DI Monkey", world.player, 11) and state.has("SM Monkey", world.player, 6)
and state.has("FR Monkey", world.player, 9) and state.has("HS Monkey", world.player, 9)
and state.has("ST Monkey", world.player, 12) and state.has("WSW Monkey", world.player, 10)
and state.has("CrC Monkey", world.player, 20) and state.has("CP Monkey", world.player, 13)
and state.has("SF Monkey", world.player, 10) and state.has("TVT Monkey", world.player, 12)
and state.has("MM Monkey", world.player, 24))
'''
# '''
''' can_reach checking - seems to error out sometimes. NOTE: Add "# " to the beginning to uncomment.
locs_to_check = [
AELocation.W1L1Noonan.value, AELocation.W1L1Jorjy.value, AELocation.W1L1Nati.value,
AELocation.W1L1TrayC.value, AELocation.W1L2Shay.value, AELocation.W1L2DrMonk.value,
AELocation.W1L2Grunt.value, AELocation.W1L2Ahchoo.value, AELocation.W1L2Gornif.value,
AELocation.W1L2Tyrone.value, AELocation.W1L3Scotty.value, AELocation.W1L3Coco.value,
AELocation.W1L3JThomas.value, AELocation.W1L3Mattie.value, AELocation.W1L3Barney.value,
AELocation.W1L3Rocky.value, AELocation.W1L3Moggan.value, AELocation.W2L1Marquez.value,
AELocation.W2L1Livinston.value, AELocation.W2L1George.value, AELocation.W2L1Maki.value,
AELocation.W2L1Herb.value, AELocation.W2L1Dilweed.value, AELocation.W2L1Mitong.value,
AELocation.W2L1Stoddy.value, AELocation.W2L1Nasus.value, AELocation.W2L1Selur.value,
AELocation.W2L1Elehcim.value, AELocation.W2L1Gonzo.value, AELocation.W2L1Alphonse.value,
AELocation.W2L1Zanzibar.value, AELocation.W2L2Mooshy.value, AELocation.W2L2Kyle.value,
AELocation.W2L2Cratman.value, AELocation.W2L2Nuzzy.value, AELocation.W2L2Mav.value,
AELocation.W2L2Stan.value, AELocation.W2L2Bernt.value, AELocation.W2L2Runt.value,
AELocation.W2L2Hoolah.value, AELocation.W2L2Papou.value, AELocation.W2L2Kenny.value,
AELocation.W2L2Trance.value, AELocation.W2L2Chino.value, AELocation.W2L3Troopa.value,
AELocation.W2L3Spanky.value, AELocation.W2L3Stymie.value, AELocation.W2L3Pally.value,
AELocation.W2L3Freeto.value, AELocation.W2L3Jesta.value, AELocation.W2L3Bazzle.value,
AELocation.W2L3Crash.value, AELocation.W4L1CoolBlue.value, AELocation.W4L1Sandy.value,
AELocation.W4L1ShellE.value, AELocation.W4L1Gidget.value, AELocation.W4L1Shaka.value,
AELocation.W4L1MaxMahalo.value, AELocation.W4L1Moko.value, AELocation.W4L1Puka.value,
AELocation.W4L2Chip.value, AELocation.W4L2Oreo.value, AELocation.W4L2Puddles.value,
AELocation.W4L2Kalama.value, AELocation.W4L2Iz.value, AELocation.W4L2Jux.value,
AELocation.W4L2BongBong.value, AELocation.W4L2Pickles.value, AELocation.W4L3Stuw.value,
AELocation.W4L3TonTon.value, AELocation.W4L3Murky.value, AELocation.W4L3Howeerd.value,
AELocation.W4L3Robbin.value, AELocation.W4L3Jakkee.value, AELocation.W4L3Frederic.value,
AELocation.W4L3Baba.value, AELocation.W4L3Mars.value, AELocation.W4L3Horke.value,
AELocation.W4L3Quirck.value, AELocation.W5L1Popcicle.value, AELocation.W5L1Iced.value,
AELocation.W5L1Denggoy.value, AELocation.W5L1Skeens.value, AELocation.W5L1Rickets.value,
AELocation.W5L1Chilly.value, AELocation.W5L2Storm.value, AELocation.W5L2Qube.value,
AELocation.W5L2Gash.value, AELocation.W5L2Kundra.value, AELocation.W5L2Shadow.value,
AELocation.W5L2Ranix.value, AELocation.W5L2Sticky.value, AELocation.W5L2Sharpe.value,
AELocation.W5L2Droog.value, AELocation.W5L3Punky.value, AELocation.W5L3Ameego.value,
AELocation.W5L3Roti.value, AELocation.W5L3Dissa.value, AELocation.W5L3Yoky.value,
AELocation.W5L3Jory.value, AELocation.W5L3Crank.value, AELocation.W5L3Claxter.value,
AELocation.W5L3Looza.value, AELocation.W7L1Taku.value, AELocation.W7L1Rocka.value,
AELocation.W7L1Maralea.value, AELocation.W7L1Wog.value, AELocation.W7L1Long.value,
AELocation.W7L1Mayi.value, AELocation.W7L1Owyang.value, AELocation.W7L1QuelTin.value,
AELocation.W7L1Phaldo.value, AELocation.W7L1Voti.value, AELocation.W7L1Elly.value,
AELocation.W7L1Chunky.value, AELocation.W7L2Minky.value, AELocation.W7L2Zobbro.value,
AELocation.W7L2Xeeto.value, AELocation.W7L2Moops.value, AELocation.W7L2Zanabi.value,
AELocation.W7L2Buddha.value, AELocation.W7L2Fooey.value, AELocation.W7L2Doxs.value,
AELocation.W7L2Kong.value, AELocation.W7L2Phool.value, AELocation.W7L3Naners.value,
AELocation.W7L3Robart.value, AELocation.W7L3Neeners.value, AELocation.W7L3Gustav.value,
AELocation.W7L3Wilhelm.value, AELocation.W7L3Emmanuel.value, AELocation.W7L3SirCutty.value,
AELocation.W7L3Calligan.value, AELocation.W7L3Castalist.value, AELocation.W7L3Deveneom.value,
AELocation.W7L3Igor.value, AELocation.W7L3Charles.value, AELocation.W7L3Astur.value,
AELocation.W7L3Kilserack.value, AELocation.W7L3Ringo.value, AELocation.W7L3Densil.value,
AELocation.W7L3Figero.value, AELocation.W7L3Fej.value, AELocation.W7L3Joey.value,
AELocation.W7L3Donqui.value, AELocation.W8L1Kaine.value, AELocation.W8L1Jaxx.value,
AELocation.W8L1Gehry.value, AELocation.W8L1Alcatraz.value, AELocation.W8L1Tino.value,
AELocation.W8L1QBee.value, AELocation.W8L1McManic.value, AELocation.W8L1Dywan.value,
AELocation.W8L1CKHutch.value, AELocation.W8L1Winky.value, AELocation.W8L1BLuv.value,
AELocation.W8L1Camper.value, AELocation.W8L1Huener.value, AELocation.W8L2BigShow.value,
AELocation.W8L2Dreos.value, AELocation.W8L2Reznor.value, AELocation.W8L2Urkel.value,
AELocation.W8L2VanillaS.value, AELocation.W8L2Radd.value, AELocation.W8L2Shimbo.value,
AELocation.W8L2Hurt.value, AELocation.W8L2String.value, AELocation.W8L2Khamo.value,
AELocation.W8L3Fredo.value, AELocation.W8L3Charlee.value, AELocation.W8L3Mach3.value,
AELocation.W8L3Tortuss.value, AELocation.W8L3Manic.value, AELocation.W8L3Ruptdis.value,
AELocation.W8L3Eighty7.value, AELocation.W8L3Danio.value, AELocation.W8L3Roosta.value,
AELocation.W8L3Tellis.value, AELocation.W8L3Whack.value, AELocation.W8L3Frostee.value,
AELocation.W9L1Goopo.value, AELocation.W9L1Porto.value, AELocation.W9L1Slam.value,
AELocation.W9L1Junk.value, AELocation.W9L1Crib.value, AELocation.W9L1Nak.value,
AELocation.W9L1Cloy.value, AELocation.W9L1Shaw.value, AELocation.W9L1Flea.value,
AELocation.W9L1Schafette.value, AELocation.W9L1Donovan.value, AELocation.W9L1Laura.value,
AELocation.W9L1Uribe.value, AELocation.W9L1Gordo.value, AELocation.W9L1Raeski.value,
AELocation.W9L1Poopie.value, AELocation.W9L1Teacup.value, AELocation.W9L1Shine.value,
AELocation.W9L1Wrench.value, AELocation.W9L1Bronson.value, AELocation.W9L1Bungee.value,
AELocation.W9L1Carro.value, AELocation.W9L1Carlito.value, AELocation.W9L1BG.value
]
locs_accessible = CountAccessibleLocations(state, world, locs_to_check)
return locs_accessible >= 204
'''
# '''
# Using this method seems to cause race condition errors in playthrough calculation?
def CountAccessibleLocations(state, world, locs_to_check):
locs_accessible = 0
for x in range(len(locs_to_check)):
if state.can_reach(world.get_region(locs_to_check[x]), "Region", world.player):
locs_accessible = locs_accessible + 1
return locs_accessible
# Entrance Shuffle Helper Functions
def initialize_level_list(setlevelids = None):
baselevelnames = ["Fossil Field", "Primordial Ooze", "Molten Lava", "Thick Jungle", "Dark Ruins", "Cryptic Relics", "Stadium Attack", "Crabby Beach", "Coral Cave", "Dexter's Island", "Snowy Mammoth", "Frosty Retreat", "Hot Springs", "Gladiator Attack", "Sushi Temple", "Wabi Sabi Wall", "Crumbling Castle", "City Park", "Specter's Factory", "TV Tower", "Monkey Madness", "Peak Point Matrix"]
baselevelids = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11,
0x14, 0x15, 0x16, 0x18, 0x1E]
# If not using UT, use the vanilla list
if setlevelids is None:
levelids = baselevelids
levelnames = baselevelnames
# Using UT, will replace the vanilla list with the already shuffled one
else:
levelnames = [baselevelnames[baselevelids.index(setlevelids[x])] for x in range(0, 22)]
levelids = setlevelids
levellist = []
for x in range (0, 22):
# Vanilla position
if setlevelids is None:
vanillapos = x
# Using UT: will get the vanilla level order of the level in the shuffled list
else:
vanillapos = baselevelids.index(setlevelids[x])
levellist.append(ApeEscapeLevel(levelnames[x], levelids[x], vanillapos))
return levellist
def initialize_room_list(world, roomsperlevel, setlevelids = None, setroomids = None):
# baselevelnames = ["Fossil Field", "Primordial Ooze", "Molten Lava", "Thick Jungle", "Dark Ruins", "Cryptic Relics", "Stadium Attack", "Crabby Beach", "Coral Cave", "Dexter's Island", "Snowy Mammoth", "Frosty Retreat", "Hot Springs", "Gladiator Attack", "Sushi Temple", "Wabi Sabi Wall", "Crumbling Castle", "City Park", "Specter's Factory", "TV Tower", "Monkey Madness", "Peak Point Matrix"]
baselevelids = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x14, 0x15, 0x16, 0x18, 0x1E]
firstroomids = [0x01, 0x02, 0x03, 0x06, 0x0B, 0x0F, 0x13, 0x14, 0x16, 0x18, 0x1D, 0x1E, 0x21, 0x24, 0x25, 0x28, 0x2D, 0x35, 0x38, 0x3F, 0x45, 0x57]
firstroomlist = []
# Using UT, will replace the vanilla list with the already shuffled one
if world.using_ut == True:
levelids = setlevelids
orderedfirstroomids = setroomids
else:
levelids = [world.levellist[x].entrance for x in range(0, 22)]
orderedfirstroomids = []
excludedrooms_LampsOff = [27] # Exclude certain rooms if LampShuffle is off
excludedrooms = []
for x in range (0, 22):
levelrooms = list(roomsperlevel[levelids[x]])
# Rooms exclusion
levelrooms = [item for item in levelrooms if item not in excludedrooms]
# Exclude some rooms if Lamps are not shuffled, to prevent getting stuck
if world.options.lamp == 0x00:
levelrooms = [item for item in levelrooms if item not in excludedrooms_LampsOff]
levelrooms.sort()
if world.options.randomizestartingroom == 0x00: # Option off
orderedfirstroomids.append(levelrooms[0])
else:
if setroomids:
orderedfirstroomids.append(levelids[x])
else:
randomroom = world.random.randint(0, len(levelrooms) - 1)
orderedfirstroomids.append(levelrooms[randomroom])
return orderedfirstroomids
def level_to_bytes(name):
bytelist = []
for x in name:
bytelist.append(character_lookup(x))
return bytelist
def character_lookup(byte):
if byte.isspace(): # Space
return 255
if byte.isalpha():
return ord(byte) - 49 # Both uppercase and lowercase letters
if byte.isdecimal():
if int(byte) < 6:
return ord(byte) + 58 # 0-5
else:
return ord(byte) + 68 # 6-9
if ord(byte) == 39: # Single apostrophe
return 187
if ord(byte) == 46: # Period
return 172
if ord(byte) == 47: # Slash
return 141
if ord(byte) == 58: # Colon
return 174
def fixed_levels(levellist, entoption, coinoption, goaloption):
# Reset position of Peak Point Matrix for mm (postgame), ppm and ppm token (endgame)
# If MM is locked and mmtoken is the goal, then place PPM at the end anyway
if goaloption == 0x00 or goaloption == 0x01 or goaloption == 0x04 or (entoption == 0x02 and goaloption == 0x03):
for x in range (0, 22):
if levellist[x].entrance == 0x1E:
levellist[x], levellist[21] = levellist[21], levellist[x]
# Reset position of Monkey Madness if the option requires it
if entoption == 0x02:
for x in range (0, 22):
if levellist[x].entrance == 0x18:
levellist[x], levellist[20] = levellist[20], levellist[x]
# Reset position of races if coin shuffle isn't on
if coinoption == 0x00:
for x in range (0, 22):
if levellist[x].entrance == 0x07: # Stadium Attack
levellist[x], levellist[6] = levellist[6], levellist[x]
for x in range (0, 22):
if levellist[x].entrance == 0x0E: # Gladiator Attack
levellist[x], levellist[13] = levellist[13], levellist[x]
return levellist
def set_calculated_level_data(levellist, keyoption, goaloption, coinoption):
reqkeys = get_required_keys(keyoption, goaloption, coinoption)
for x in range (0, 22):
levellist[x].bytes = level_to_bytes(levellist[x].name)
levellist[x].keys = reqkeys[x]
levellist[x].newpos = x
return levellist
def get_required_keys(key, goal, coin):
reqkeys = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
if key == 0x03: # none
return reqkeys
if key == 0x00: # world
reqkeys = [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6]
if key == 0x01: # level
reqkeys = [0, 0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 16]
if key == 0x02: # two
reqkeys = [0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8]
if goal == 0x02 or goal == 0x03 or goal == 0x04: # If PPM unlocks only by keys, make it unlock later than MM.
reqkeys[21] = reqkeys[21] + 1
if coin == 0x01: # If the races have locations, make everything after them require an extra key for each.
for x in range (7, 22):
reqkeys[x] = reqkeys[x] + 1
for x in range (14, 22):
reqkeys[x] = reqkeys[x] + 1
return reqkeys