Refactor OWG rules to keep them separate from no glitches.

Add logic for superbunny access to Sahasrahla's closet (with boots)
Add logic for superbunny through Two Brother's House (with boots)
Fix superbunny logic for spiral cave and mini moldorm cave - requires a sword
Add logic for waterwalking into Waterfall Cave
Add clip to Ice Palace entrance (requires boots, pearl and flippers)
Add extra clips to inverted owg logic - PoD and Dark Lake Hylia Ledge are now in logic with just boots
Add clip to flute point 6 into inverted owg logic - some light world locations are now accessible with boots and mitts, but no pearl or mirror.
This commit is contained in:
compiling
2020-10-30 17:04:36 +11:00
parent 82449763b7
commit b1853e2ad9
7 changed files with 328 additions and 429 deletions

View File

@@ -3063,50 +3063,14 @@ mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia Central
('Ganons Tower Moldorm Door', 'Ganons Tower (Moldorm)'), ('Ganons Tower Moldorm Door', 'Ganons Tower (Moldorm)'),
('Ganons Tower Moldorm Gap', 'Agahnim 2'), ('Ganons Tower Moldorm Gap', 'Agahnim 2'),
('Ganon Drop', 'Bottom of Pyramid'), ('Ganon Drop', 'Bottom of Pyramid'),
('Pyramid Drop', 'East Dark World'), ('Pyramid Drop', 'East Dark World')
('Light World DMA Clip Spot', 'Death Mountain'),
('Hera Ascent', 'Death Mountain (Top)'),
('Spectacle Rock Clip Spot', 'Spectacle Rock'),
('Death Mountain Return Ledge Clip Spot', 'Death Mountain Return Ledge'),
('Death Mountain Glitched Bridge', 'East Death Mountain (Top)'),
('Floating Island Clip Spot', 'Death Mountain Floating Island (Light World)'),
('Dark Death Mountain Ledge Clip Spot', 'Dark Death Mountain Ledge'),
('Zora Descent Clip Spot', 'Zoras River'),
#todo: Entrances shouldn't lead to multiple regions. This currently works, but it's fragile
('Graveyard Ledge Clip Spot', 'Graveyard Ledge'),
('Graveyard Ledge Clip Spot', 'Kings Grave Area'),
('Desert Northern Cliffs', 'Desert Ledge'),
('Desert Northern Cliffs', 'Desert Ledge (Northeast)'),
('Desert Northern Cliffs', 'Desert Palace Entrance (North) Spot'),
('Lake Hylia Island Clip Spot', 'Lake Hylia Island'),
('Dark World DMA Clip Spot', 'Dark Death Mountain (West Bottom)'),
('Ganons Tower Ascent', 'Dark Death Mountain (Top)'),
('Bumper Cave Ledge Clip Spot', 'Bumper Cave Ledge'),
('Dark Death Mountain Glitched Bridge', 'Dark Death Mountain (Top)'),
('Dark Death Mountain Bunny Descent Mirror Spot', 'Dark Death Mountain Bunny Descent Area'),
('Catfish Descent', 'Catfish'),
('Dark Death Mountain Offset Mirror', 'East Dark World'),
('Hammer Pegs River Clip Spot', 'Hammer Peg Area'),
('Dark Lake Hylia Ledge Clip Spot', 'Dark Lake Hylia Ledge'),
('Dark Desert Cliffs Clip Spot', 'Dark Desert'),
('Bumper Cave Ledge Clip Spot', 'Bumper Cave Entrance'),
('Death Mountain Return Ledge Clip Spot', 'Death Mountain Entrance'),
('West Dark World Bunny Descent', 'West Dark World'),
('Dark Death Mountain (East Bottom) Jump', 'Dark Death Mountain (East Bottom)'),
('Bat Cave River Clip Spot', 'Bat Cave Drop Ledge'),
('Turtle Rock (Top) Clip Spot', 'Turtle Rock (Top)'),
('Dark Death Mountain Descent', 'West Dark World'),
('Death Mountain Descent', 'Light World'),
('Bombos Tablet Clip Spot', 'Bombos Tablet Ledge'),
('Cave 45 Clip Spot', 'Cave 45 Ledge'),
] ]
inverted_mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), inverted_mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'),
('Lake Hylia Island Pier', 'Lake Hylia Island'), ('Lake Hylia Island Pier', 'Lake Hylia Island'),
('Lake Hylia Warp', 'Northeast Light World'), ('Lake Hylia Warp', 'Northeast Light World'),
('Northeast Light World Warp', 'Light World'), ('Northeast Light World Warp', 'Light World'),
('Zoras River', 'Zoras River'), ('Zoras River', 'Zoras River'),
('Graveyard Ledge Clip Spot', 'Kings Grave Area'),
('Kings Grave Outer Rocks', 'Kings Grave Area'), ('Kings Grave Outer Rocks', 'Kings Grave Area'),
('Kings Grave Inner Rocks', 'Light World'), ('Kings Grave Inner Rocks', 'Light World'),
('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'),
@@ -3319,32 +3283,7 @@ inverted_mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia
('Bush Covered Lawn Mirror Spot', 'Dark Grassy Lawn'), ('Bush Covered Lawn Mirror Spot', 'Dark Grassy Lawn'),
('Bomb Hut Inner Bushes', 'Light World'), ('Bomb Hut Inner Bushes', 'Light World'),
('Bomb Hut Outer Bushes', 'Bomb Hut Area'), ('Bomb Hut Outer Bushes', 'Bomb Hut Area'),
('Bomb Hut Mirror Spot', 'West Dark World'), ('Bomb Hut Mirror Spot', 'West Dark World')]
('Light World DMA Clip Spot', 'Death Mountain'),
('Hera Ascent', 'Death Mountain (Top)'),
('Death Mountain Return Ledge Clip Spot', 'Death Mountain Return Ledge'),
('Death Mountain Glitched Bridge', 'East Death Mountain (Top)'),
('Dark Death Mountain Ledge Clip Spot', 'Dark Death Mountain Ledge'),
('Zora Descent Clip Spot', 'Zoras River'),
('Desert Northern Cliffs', 'Desert Ledge'),
('Desert Northern Cliffs', 'Desert Palace Entrance (North) Spot'),
('Lake Hylia Island Clip Spot', 'Lake Hylia Island'),
('Dark World DMA Clip Spot', 'Dark Death Mountain'),
('Bumper Cave Ledge Clip Spot', 'Bumper Cave Ledge'),
('Catfish Descent', 'Catfish'),
('Death Mountain Offset Mirror', 'Light World'),
('Hammer Pegs River Clip Spot', 'Hammer Peg Area'),
('Dark Lake Hylia Ledge Clip Spot', 'Dark Lake Hylia Ledge'),
('Dark Desert Cliffs Clip Spot', 'Dark Desert'),
('Bumper Cave Ledge Clip Spot', 'Bumper Cave Entrance'),
('Death Mountain Return Ledge Clip Spot', 'Death Mountain Entrance'),
('Light World Bunny Descent', 'Light World'),
('East Death Mountain (Bottom) Jump', 'East Death Mountain (Bottom)'),
('Bat Cave River Clip Spot', 'Bat Cave Drop Ledge'),
('Turtle Rock (Top) Clip Spot', 'Turtle Rock (Top)'),
('Dark Death Mountain Descent', 'West Dark World'),
('Death Mountain Descent', 'Light World'),
('Death Mountain Bunny Descent Mirror Spot', 'Death Mountain Bunny Descent Area')]
# non-shuffled entrance links # non-shuffled entrance links
default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'), default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'),
("Blinds Hideout", "Blinds Hideout"), ("Blinds Hideout", "Blinds Hideout"),

View File

@@ -17,8 +17,7 @@ def create_inverted_regions(world, player):
'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game',
'East Dark World Mirror Spot', 'West Dark World Mirror Spot', 'South Dark World Mirror Spot', 'Cave 45', 'Checkerboard Cave', 'Mire Mirror Spot', 'Hammer Peg Area Mirror Spot', 'East Dark World Mirror Spot', 'West Dark World Mirror Spot', 'South Dark World Mirror Spot', 'Cave 45', 'Checkerboard Cave', 'Mire Mirror Spot', 'Hammer Peg Area Mirror Spot',
'Shopping Mall Mirror Spot', 'Skull Woods Mirror Spot', 'Inverted Pyramid Entrance','Hyrule Castle Entrance (South)', 'Secret Passage Outer Bushes', 'Bush Covered Lawn Outer Bushes', 'Shopping Mall Mirror Spot', 'Skull Woods Mirror Spot', 'Inverted Pyramid Entrance','Hyrule Castle Entrance (South)', 'Secret Passage Outer Bushes', 'Bush Covered Lawn Outer Bushes',
'Potion Shop Outer Bushes', 'Graveyard Cave Outer Bushes', 'Bomb Hut Outer Bushes', 'Light World DMA Clip Spot', 'Death Mountain Return Ledge Clip Spot', 'Bat Cave River Clip Spot', 'Potion Shop Outer Bushes', 'Graveyard Cave Outer Bushes', 'Bomb Hut Outer Bushes']),
'Desert Northern Cliffs', 'Lake Hylia Island Clip Spot']),
create_lw_region(player, 'Bush Covered Lawn', None, ['Bush Covered House', 'Bush Covered Lawn Inner Bushes', 'Bush Covered Lawn Mirror Spot']), create_lw_region(player, 'Bush Covered Lawn', None, ['Bush Covered House', 'Bush Covered Lawn Inner Bushes', 'Bush Covered Lawn Mirror Spot']),
create_lw_region(player, 'Bomb Hut Area', None, ['Light World Bomb Hut', 'Bomb Hut Inner Bushes', 'Bomb Hut Mirror Spot']), create_lw_region(player, 'Bomb Hut Area', None, ['Light World Bomb Hut', 'Bomb Hut Inner Bushes', 'Bomb Hut Mirror Spot']),
create_lw_region(player, 'Hyrule Castle Secret Entrance Area', None, ['Hyrule Castle Secret Entrance Stairs', 'Secret Passage Inner Bushes']), create_lw_region(player, 'Hyrule Castle Secret Entrance Area', None, ['Hyrule Castle Secret Entrance Stairs', 'Secret Passage Inner Bushes']),
@@ -125,8 +124,7 @@ def create_inverted_regions(world, player):
create_cave_region(player, 'Old Man House', 'a connector', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']), create_cave_region(player, 'Old Man House', 'a connector', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']),
create_cave_region(player, 'Old Man House Back', 'a connector', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']), create_cave_region(player, 'Old Man House Back', 'a connector', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']),
create_lw_region(player, 'Death Mountain', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', create_lw_region(player, 'Death Mountain', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave',
'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Broken Bridge (West)', 'Death Mountain Mirror Spot', 'Death Mountain Bunny Descent Mirror Spot', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Broken Bridge (West)', 'Death Mountain Mirror Spot']),
'Death Mountain Offset Mirror', 'Hera Ascent', 'Death Mountain Glitched Bridge', 'Death Mountain Descent', 'Graveyard Ledge Clip Spot']),
create_cave_region(player, 'Death Mountain Return Cave', 'a connector', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']), create_cave_region(player, 'Death Mountain Return Cave', 'a connector', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']),
create_lw_region(player, 'Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)', 'Bumper Cave Ledge Mirror Spot']), create_lw_region(player, 'Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)', 'Bumper Cave Ledge Mirror Spot']),
create_cave_region(player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']), create_cave_region(player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']),
@@ -147,7 +145,7 @@ def create_inverted_regions(world, player):
create_cave_region(player, 'Paradox Cave', 'a connector', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']), create_cave_region(player, 'Paradox Cave', 'a connector', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']),
create_cave_region(player, 'Light World Death Mountain Shop', 'a common shop'), create_cave_region(player, 'Light World Death Mountain Shop', 'a common shop'),
create_lw_region(player, 'East Death Mountain (Top)', ['Floating Island'], ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'East Death Mountain Mirror Spot (Top)', 'Fairy Ascension Ledge Access', 'Mimic Cave Ledge Access', create_lw_region(player, 'East Death Mountain (Top)', ['Floating Island'], ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'East Death Mountain Mirror Spot (Top)', 'Fairy Ascension Ledge Access', 'Mimic Cave Ledge Access',
'Floating Island Mirror Spot', 'Zora Descent Clip Spot']), 'Floating Island Mirror Spot']),
create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Cave', 'Spiral Cave Ledge Drop', 'Dark Death Mountain Ledge Mirror Spot (West)']), create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Cave', 'Spiral Cave Ledge Drop', 'Dark Death Mountain Ledge Mirror Spot (West)']),
create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Cave', 'Mimic Cave Ledge Drop', 'Dark Death Mountain Ledge Mirror Spot (East)']), create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Cave', 'Mimic Cave Ledge Drop', 'Dark Death Mountain Ledge Mirror Spot (East)']),
create_cave_region(player, 'Spiral Cave (Top)', 'a connector', ['Spiral Cave'], ['Spiral Cave (top to bottom)', 'Spiral Cave Exit (Top)']), create_cave_region(player, 'Spiral Cave (Top)', 'a connector', ['Spiral Cave'], ['Spiral Cave (top to bottom)', 'Spiral Cave Exit (Top)']),
@@ -164,14 +162,13 @@ def create_inverted_regions(world, player):
create_dungeon_region(player, 'Tower of Hera (Top)', 'Tower of Hera', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Boss', 'Tower of Hera - Prize']), create_dungeon_region(player, 'Tower of Hera (Top)', 'Tower of Hera', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Boss', 'Tower of Hera - Prize']),
create_dw_region(player, 'East Dark World', ['Pyramid'], ['Pyramid Fairy', 'South Dark World Bridge', 'Palace of Darkness', 'Dark Lake Hylia Drop (East)', create_dw_region(player, 'East Dark World', ['Pyramid'], ['Pyramid Fairy', 'South Dark World Bridge', 'Palace of Darkness', 'Dark Lake Hylia Drop (East)',
'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Northeast Dark World Broken Bridge Pass', 'East Dark World Teleporter', 'EDW Flute', 'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Northeast Dark World Broken Bridge Pass', 'East Dark World Teleporter', 'EDW Flute']),
'Hammer Pegs River Clip Spot', 'Dark Lake Hylia Ledge Clip Spot']),
create_dw_region(player, 'Catfish', ['Catfish'], ['Catfish Exit Rock']), create_dw_region(player, 'Catfish', ['Catfish'], ['Catfish Exit Rock']),
create_dw_region(player, 'Northeast Dark World', None, ['West Dark World Gap', 'Dark World Potion Shop', 'East Dark World Broken Bridge Pass', 'NEDW Flute', 'Dark Lake Hylia Teleporter', 'Catfish Entrance Rock']), create_dw_region(player, 'Northeast Dark World', None, ['West Dark World Gap', 'Dark World Potion Shop', 'East Dark World Broken Bridge Pass', 'NEDW Flute', 'Dark Lake Hylia Teleporter', 'Catfish Entrance Rock']),
create_cave_region(player, 'Palace of Darkness Hint', 'a storyteller'), create_cave_region(player, 'Palace of Darkness Hint', 'a storyteller'),
create_cave_region(player, 'East Dark World Hint', 'a storyteller'), create_cave_region(player, 'East Dark World Hint', 'a storyteller'),
create_dw_region(player, 'South Dark World', ['Stumpy', 'Digging Game'], ['Dark Lake Hylia Drop (South)', 'Hype Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock', 'East Dark World Bridge', 'Inverted Links House', 'Archery Game', 'Bonk Fairy (Dark)', create_dw_region(player, 'South Dark World', ['Stumpy', 'Digging Game'], ['Dark Lake Hylia Drop (South)', 'Hype Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock', 'East Dark World Bridge', 'Inverted Links House', 'Archery Game', 'Bonk Fairy (Dark)',
'Dark Lake Hylia Shop', 'South Dark World Teleporter', 'Post Aga Teleporter', 'SDW Flute', 'Dark Desert Cliffs Clip Spot']), 'Dark Lake Hylia Shop', 'South Dark World Teleporter', 'Post Aga Teleporter', 'SDW Flute']),
create_cave_region(player, 'Inverted Big Bomb Shop', 'the bomb shop'), create_cave_region(player, 'Inverted Big Bomb Shop', 'the bomb shop'),
create_cave_region(player, 'Archery Game', 'a game of skill'), create_cave_region(player, 'Archery Game', 'a game of skill'),
create_dw_region(player, 'Dark Lake Hylia', None, ['East Dark World Pier', 'Dark Lake Hylia Ledge Pier', 'Ice Palace', 'Dark Lake Hylia Central Island Teleporter']), create_dw_region(player, 'Dark Lake Hylia', None, ['East Dark World Pier', 'Dark Lake Hylia Ledge Pier', 'Ice Palace', 'Dark Lake Hylia Central Island Teleporter']),
@@ -182,7 +179,7 @@ def create_inverted_regions(world, player):
'Hype Cave - Bottom', 'Hype Cave - Generous Guy']), 'Hype Cave - Bottom', 'Hype Cave - Generous Guy']),
create_dw_region(player, 'West Dark World', ['Frog'], ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Bumper Cave Entrance Rock', create_dw_region(player, 'West Dark World', ['Frog'], ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Bumper Cave Entrance Rock',
'Skull Woods Forest', 'Village of Outcasts Pegs', 'Village of Outcasts Eastern Rocks', 'Red Shield Shop', 'Inverted Dark Sanctuary', 'Fortune Teller (Dark)', 'Dark World Lumberjack Shop', 'Skull Woods Forest', 'Village of Outcasts Pegs', 'Village of Outcasts Eastern Rocks', 'Red Shield Shop', 'Inverted Dark Sanctuary', 'Fortune Teller (Dark)', 'Dark World Lumberjack Shop',
'West Dark World Teleporter', 'WDW Flute', 'Dark World DMA Clip Spot', 'Bumper Cave Ledge Clip Spot']), 'West Dark World Teleporter', 'WDW Flute']),
create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop', 'Dark Grassy Lawn Flute']), create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop', 'Dark Grassy Lawn Flute']),
create_dw_region(player, 'Hammer Peg Area', ['Dark Blacksmith Ruins'], ['Dark World Hammer Peg Cave', 'Peg Area Rocks', 'Hammer Peg Area Flute']), create_dw_region(player, 'Hammer Peg Area', ['Dark Blacksmith Ruins'], ['Dark World Hammer Peg Cave', 'Peg Area Rocks', 'Hammer Peg Area Flute']),
create_dw_region(player, 'Bumper Cave Entrance', None, ['Bumper Cave (Bottom)', 'Bumper Cave Entrance Drop']), create_dw_region(player, 'Bumper Cave Entrance', None, ['Bumper Cave (Bottom)', 'Bumper Cave Entrance Drop']),
@@ -207,9 +204,7 @@ def create_inverted_regions(world, player):
create_cave_region(player, 'Mire Shed', 'a cave with two chests', ['Mire Shed - Left', 'Mire Shed - Right']), create_cave_region(player, 'Mire Shed', 'a cave with two chests', ['Mire Shed - Left', 'Mire Shed - Right']),
create_cave_region(player, 'Dark Desert Hint', 'a storyteller'), create_cave_region(player, 'Dark Desert Hint', 'a storyteller'),
create_dw_region(player, 'Dark Death Mountain', None, ['Dark Death Mountain Drop (East)', 'Inverted Agahnims Tower', 'Superbunny Cave (Top)', 'Hookshot Cave', 'Turtle Rock', create_dw_region(player, 'Dark Death Mountain', None, ['Dark Death Mountain Drop (East)', 'Inverted Agahnims Tower', 'Superbunny Cave (Top)', 'Hookshot Cave', 'Turtle Rock',
'Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'Turtle Rock Tail Drop', 'DDM Flute', 'Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'Turtle Rock Tail Drop', 'DDM Flute']),
'Dark Death Mountain Ledge Clip Spot', 'Catfish Descent', 'Turtle Rock (Top) Clip Spot',
'Dark Death Mountain Descent']),
create_dw_region(player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)']), create_dw_region(player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)']),
create_dw_region(player, 'Turtle Rock (Top)', None, ['Dark Death Mountain Teleporter (East)', 'Turtle Rock Drop']), create_dw_region(player, 'Turtle Rock (Top)', None, ['Dark Death Mountain Teleporter (East)', 'Turtle Rock Drop']),
create_dw_region(player, 'Dark Death Mountain Isolated Ledge', None, ['Turtle Rock Isolated Ledge Entrance']), create_dw_region(player, 'Dark Death Mountain Isolated Ledge', None, ['Turtle Rock Isolated Ledge Entrance']),
@@ -303,10 +298,12 @@ def create_inverted_regions(world, player):
create_cave_region(player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']), create_cave_region(player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']),
create_cave_region(player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']), create_cave_region(player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']),
create_dw_region(player, 'Pyramid Ledge', None, ['Pyramid Drop']), # houlihan room exits here in inverted create_dw_region(player, 'Pyramid Ledge', None, ['Pyramid Drop']), # houlihan room exits here in inverted
create_dw_region(player, 'Death Mountain Bunny Descent Area', None, ['Light World Bunny Descent', 'East Death Mountain (Bottom) Jump']),
# to simplify flute connections # to simplify flute connections
create_cave_region(player, 'The Sky', 'A Dark Sky', None, ['DDM Landing','NEDW Landing', 'WDW Landing', 'SDW Landing', 'EDW Landing', 'DD Landing', 'DLHL Landing']) create_cave_region(player, 'The Sky', 'A Dark Sky', None, ['DDM Landing','NEDW Landing', 'WDW Landing', 'SDW Landing', 'EDW Landing', 'DD Landing', 'DLHL Landing']),
create_lw_region(player, 'Desert Northern Cliffs'),
create_lw_region(player, 'Death Mountain Bunny Descent Area')
] ]
for region_name, (room_id, shopkeeper, replaceable) in shop_table.items(): for region_name, (room_id, shopkeeper, replaceable) in shop_table.items():

81
Main.py
View File

@@ -187,85 +187,6 @@ def gt_filler(world):
return random.randint(15, 50) return random.randint(15, 50)
return random.randint(0, 15) return random.randint(0, 15)
def copy_world(world):
# ToDo: Not good yet
ret = World(world.players, world.shuffle, world.logic, world.mode, world.swords, world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm, world.place_dungeon_items, world.accessibility, world.shuffle_ganon, world.quickswap, world.fastmenu, world.disable_music, world.keysanity, world.retro, world.custom, world.customitemarray, world.boss_shuffle, world.hints)
ret.required_medallions = world.required_medallions.copy()
ret.swamp_patch_required = world.swamp_patch_required.copy()
ret.ganon_at_pyramid = world.ganon_at_pyramid.copy()
ret.powder_patch_required = world.powder_patch_required.copy()
ret.ganonstower_vanilla = world.ganonstower_vanilla.copy()
ret.treasure_hunt_count = world.treasure_hunt_count
ret.treasure_hunt_icon = world.treasure_hunt_icon
ret.sewer_light_cone = world.sewer_light_cone
ret.light_world_light_cone = world.light_world_light_cone
ret.dark_world_light_cone = world.dark_world_light_cone
ret.seed = world.seed
ret.can_access_trock_eyebridge = world.can_access_trock_eyebridge
ret.can_access_trock_front = world.can_access_trock_front
ret.can_access_trock_big_chest = world.can_access_trock_big_chest
ret.can_access_trock_middle = world.can_access_trock_middle
ret.can_take_damage = world.can_take_damage
ret.difficulty_requirements = world.difficulty_requirements
ret.fix_fake_world = world.fix_fake_world
ret.lamps_needed_for_dark_rooms = world.lamps_needed_for_dark_rooms
ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon
ret.crystals_needed_for_gt = world.crystals_needed_for_gt
if world.mode != 'inverted':
for player in range(1, world.players + 1):
create_regions(ret, player)
create_dungeons(ret, player)
else:
for player in range(1, world.players + 1):
create_inverted_regions(ret, player)
create_dungeons(ret, player)
copy_dynamic_regions_and_locations(world, ret)
# copy bosses
for dungeon in world.dungeons:
for level, boss in dungeon.bosses.items():
ret.get_dungeon(dungeon.name, dungeon.player).bosses[level] = boss
for shop in world.shops:
copied_shop = ret.get_region(shop.region.name, shop.region.player).shop
copied_shop.active = shop.active
copied_shop.inventory = copy.copy(shop.inventory)
# connect copied world
for region in world.regions:
copied_region = ret.get_region(region.name, region.player)
copied_region.is_light_world = region.is_light_world
copied_region.is_dark_world = region.is_dark_world
for entrance in region.entrances:
ret.get_entrance(entrance.name, entrance.player).connect(copied_region)
# fill locations
for location in world.get_locations():
if location.item is not None:
item = Item(location.item.name, location.item.advancement, location.item.priority, location.item.type, player = location.item.player)
ret.get_location(location.name, location.player).item = item
item.location = ret.get_location(location.name, location.player)
if location.event:
ret.get_location(location.name, location.player).event = True
if location.locked:
ret.get_location(location.name, location.player).locked = True
# copy remaining itempool. No item in itempool should have an assigned location
for item in world.itempool:
ret.itempool.append(Item(item.name, item.advancement, item.priority, item.type, player = item.player))
# copy progress items in state
ret.state.prog_items = world.state.prog_items.copy()
ret.precollected_items = world.precollected_items.copy()
ret.state.stale = {player: True for player in range(1, world.players + 1)}
for player in range(1, world.players + 1):
set_rules(ret, player)
return ret
def copy_dynamic_regions_and_locations(world, ret): def copy_dynamic_regions_and_locations(world, ret):
for region in world.dynamic_regions: for region in world.dynamic_regions:
new_reg = Region(region.name, region.type, region.hint_text, region.player) new_reg = Region(region.name, region.type, region.hint_text, region.player)
@@ -295,7 +216,7 @@ def copy_dynamic_regions_and_locations(world, ret):
def create_playthrough(world): def create_playthrough(world):
# create a copy as we will modify it # create a copy as we will modify it
old_world = world old_world = world
world = copy_world(world) world = copy.deepcopy(world)
# if we only check for beatable, we can do this sanity check first before writing down spheres # if we only check for beatable, we can do this sanity check first before writing down spheres
if world.accessibility == 'none' and not world.can_beat_game(): if world.accessibility == 'none' and not world.can_beat_game():

View File

@@ -1,191 +0,0 @@
'''
Helper functions to deliver entrance/exit/region sets to OWG rules.
'''
def get_immediately_accessible_entrances(world, player):
'''
Entrances that are available with no items at all.
At this point, these are fake flipper spots.
'''
entrances = [
'Hobo Bridge',
'Zoras River',
'Lake Hylia Central Island Pier',
]
return entrances
def get_sword_required_superbunny_mirror_regions():
'''
Cave regions that superbunny can get through - but only with a sword.
'''
return [
'Mini Moldorm Cave',
'Spiral Cave (Top)',
]
def get_invalid_mirror_bunny_entrances_dw():
'''
Dark World entrances that can't be superbunny-mirrored into.
'''
return [
'Skull Woods Final Section (Entrance)',
'Hype Cave',
'Bonk Fairy (Dark)',
'Thieves Town',
'Dark World Hammer Peg Cave',
'Brewery',
'Hookshot Cave',
'Hookshot Cave Exit (South)',
'Dark Lake Hylia Ledge Fairy',
'Dark Lake Hylia Ledge Spike Cave',
]
def get_invalid_mirror_bunny_entrances_lw():
'''
Light World entrances that can't be superbunny-mirrored into.
'''
return [
'Bonk Rock Cave',
'Bonk Fairy (Light)',
'50 Rupee Cave',
'20 Rupee Cave',
'Checkerboard Cave',
'Light Hype Fairy',
'Waterfall of Wishing',
'Light World Bomb Hut',
'Mini Moldorm Cave',
'Ice Rod Cave',
'Sanctuary Grave',
'Kings Grave',
#todo: you can for insanity shuffle
'Hyrule Castle Secret Entrance Stairs',
'Tower of Hera',
]
def get_superbunny_accessible_locations():
'''
Interior locations that can be accessed with superbunny state.
'''
return [
'Waterfall of Wishing - Left',
'Waterfall of Wishing - Right',
'King\'s Tomb', 'Floodgate',
'Floodgate Chest',
'Cave 45',
'Bonk Rock Cave',
'Brewery',
'C-Shaped House',
'Chest Game',
'Mire Shed - Left',
'Mire Shed - Right',
'Secret Passage',
'Ice Rod Cave',
'Pyramid Fairy - Left',
'Pyramid Fairy - Right',
'Superbunny Cave - Top',
'Superbunny Cave - Bottom',
'Blind\'s Hideout - Left',
'Blind\'s Hideout - Right',
'Blind\'s Hideout - Far Left',
'Blind\'s Hideout - Far Right',
'Kakariko Well - Left',
'Kakariko Well - Middle',
'Kakariko Well - Right',
'Kakariko Well - Bottom',
'Kakariko Tavern',
'Library',
'Spiral Cave'
]
def get_boots_clip_exits_lw(inverted = False):
'''
Special Light World region exits that require boots clips.
'''
exits = [
'Bat Cave River Clip Spot',
'Light World DMA Clip Spot',
'Hera Ascent',
'Death Mountain Return Ledge Clip Spot',
'Death Mountain Glitched Bridge',
'Zora Descent Clip Spot',
'Desert Northern Cliffs',
'Lake Hylia Island Clip Spot',
'Death Mountain Descent',
'Graveyard Ledge Clip Spot',
# TODO: Why is this listed as a special OWG only entrance?
# Also requires a waterwalk setup, but the point still remains.
# 'Waterfall of Wishing',
]
if not inverted:
exits.append('Spectacle Rock Clip Spot')
exits.append('Bombos Tablet Clip Spot')
exits.append('Floating Island Clip Spot')
exits.append('Cave 45 Clip Spot')
return exits
def get_boots_clip_exits_dw(inverted = False):
'''
Special Dark World region exits that require boots clips.
'''
exits = [
'Dark World DMA Clip Spot',
'Bumper Cave Ledge Clip Spot',
'Catfish Descent',
'Hammer Pegs River Clip Spot',
'Dark Lake Hylia Ledge Clip Spot',
'Dark Desert Cliffs Clip Spot',
'Dark Death Mountain Descent',
]
if not inverted:
exits.append('Ganons Tower Ascent')
exits.append('Dark Death Mountain Glitched Bridge')
exits.append('Turtle Rock (Top) Clip Spot')
return exits
def get_glitched_speed_drops_dw():
'''
Dark World drop-down ledges that require glitched speed.
'''
return [
'Dark Death Mountain Ledge Clip Spot',
]
def get_mirror_clip_spots_dw():
'''
Mirror shenanigans that are in logic even if the player is a bunny.
'''
return [
'Dark Death Mountain Offset Mirror',
'Dark Death Mountain Bunny Descent Mirror Spot',
]
def get_mirror_clip_spots_lw():
'''
Inverted mirror shenanigans in logic even if the player is a bunny.
'''
return [
'Death Mountain Bunny Descent Mirror Spot',
'Death Mountain Offset Mirror',
]
def get_invalid_bunny_revival_dungeons():
'''
Dungeon regions that can't be bunny revived from.
'''
return [
'Tower of Hera (Bottom)',
'Swamp Palace (Entrance)',
'Turtle Rock (Entrance)',
'Sanctuary'
]

243
OverworldGlitchRules.py Normal file
View File

@@ -0,0 +1,243 @@
"""
Helper functions to deliver entrance/exit/region sets to OWG rules.
"""
from BaseClasses import Entrance
def get_sword_required_superbunny_mirror_regions():
"""
Cave regions that superbunny can get through - but only with a sword.
"""
yield 'Mini Moldorm Cave'
yield 'Spiral Cave (Top)'
def get_boots_required_superbunny_mirror_regions():
"""
Cave regions that superbunny can get through - but only with boots.
"""
yield 'Two Brothers House'
def get_boots_required_superbunny_mirror_locations():
"""
Cave locations that superbunny can access - but only with boots.
"""
yield 'Sahasrahla\'s Hut - Left'
yield 'Sahasrahla\'s Hut - Middle'
yield 'Sahasrahla\'s Hut - Right'
def get_invalid_mirror_bunny_entrances_dw():
"""
Dark World entrances that can't be superbunny-mirrored into.
"""
yield 'Skull Woods Final Section (Entrance)'
yield 'Hype Cave'
yield 'Bonk Fairy (Dark)'
yield 'Thieves Town'
yield 'Dark World Hammer Peg Cave'
yield 'Brewery'
yield 'Hookshot Cave'
yield 'Hookshot Cave Exit (South)'
yield 'Dark Lake Hylia Ledge Fairy'
yield 'Dark Lake Hylia Ledge Spike Cave'
def get_invalid_mirror_bunny_entrances_lw():
"""
Light World entrances that can't be superbunny-mirrored into.
"""
yield 'Bonk Rock Cave'
yield 'Bonk Fairy (Light)'
yield '50 Rupee Cave'
yield '20 Rupee Cave'
yield 'Checkerboard Cave'
yield 'Light Hype Fairy'
yield 'Waterfall of Wishing'
yield 'Light World Bomb Hut'
yield 'Mini Moldorm Cave'
yield 'Ice Rod Cave'
yield 'Sanctuary Grave'
yield 'Kings Grave'
#todo: you can for insanity shuffle
yield 'Hyrule Castle Secret Entrance Stairs'
yield 'Tower of Hera'
def get_superbunny_accessible_locations():
"""
Interior locations that can be accessed with superbunny state.
"""
yield 'Waterfall of Wishing - Left'
yield 'Waterfall of Wishing - Right'
yield 'King\'s Tomb'
yield 'Floodgate'
yield 'Floodgate Chest'
yield 'Cave 45'
yield 'Bonk Rock Cave'
yield 'Brewery'
yield 'C-Shaped House'
yield 'Chest Game'
yield 'Mire Shed - Left'
yield 'Mire Shed - Right'
yield 'Secret Passage'
yield 'Ice Rod Cave'
yield 'Pyramid Fairy - Left'
yield 'Pyramid Fairy - Right'
yield 'Superbunny Cave - Top'
yield 'Superbunny Cave - Bottom'
yield 'Blind\'s Hideout - Left'
yield 'Blind\'s Hideout - Right'
yield 'Blind\'s Hideout - Far Left'
yield 'Blind\'s Hideout - Far Right'
yield 'Kakariko Well - Left'
yield 'Kakariko Well - Middle'
yield 'Kakariko Well - Right'
yield 'Kakariko Well - Bottom'
yield 'Kakariko Tavern'
yield 'Library'
yield 'Spiral Cave'
for location in get_boots_required_superbunny_mirror_locations():
yield location
def get_boots_clip_exits_lw(inverted = False):
"""
Special Light World region exits that require boots clips.
"""
yield ('Bat Cave River Clip Spot', 'Light World', 'Bat Cave Drop Ledge')
yield ('Light World DMA Clip Spot', 'Light World', 'Death Mountain')
yield ('Hera Ascent', 'Death Mountain', 'Death Mountain (Top)')
yield ('Death Mountain Return Ledge Clip Spot', 'Light World', 'Death Mountain Return Ledge')
yield ('Death Mountain Entrance Clip Spot', 'Light World', 'Death Mountain Entrance')
yield ('Death Mountain Glitched Bridge', 'Death Mountain', 'East Death Mountain (Top)')
yield ('Zora Descent Clip Spot', 'East Death Mountain (Top)', 'Zoras River')
yield ('Desert Northern Cliffs', 'Light World', 'Desert Northern Cliffs')
yield ('Desert Ledge Dropdown', 'Desert Northern Cliffs', 'Desert Ledge')
yield ('Desert Palace Entrance Dropdown', 'Desert Northern Cliffs', 'Desert Palace Entrance (North) Spot')
yield ('Lake Hylia Island Clip Spot', 'Light World', 'Lake Hylia Island')
yield ('Death Mountain Descent', 'Death Mountain', 'Light World')
yield ('Kings Grave Clip Spot', 'Death Mountain', 'Kings Grave Area')
if not inverted:
yield ('Graveyard Ledge Clip Spot', 'Death Mountain', 'Graveyard Ledge')
yield ('Desert Ledge (Northeast) Dropdown', 'Desert Northern Cliffs', 'Desert Ledge (Northeast)')
yield ('Spectacle Rock Clip Spot', 'Death Mountain (Top)', 'Spectacle Rock')
yield ('Bombos Tablet Clip Spot', 'Light World', 'Bombos Tablet Ledge')
yield ('Floating Island Clip Spot', 'East Death Mountain (Top)', 'Death Mountain Floating Island (Light World)')
yield ('Cave 45 Clip Spot', 'Light World', 'Cave 45 Ledge')
def get_boots_clip_exits_dw(inverted = False):
"""
Special Dark World region exits that require boots clips.
"""
yield ('Dark World DMA Clip Spot', 'West Dark World', inverted and 'Dark Death Mountain' or 'Dark Death Mountain (West Bottom)')
yield ('Bumper Cave Ledge Clip Spot', 'West Dark World', 'Bumper Cave Ledge')
yield ('Bumper Cave Entrance Clip Spot', 'West Dark World', 'Bumper Cave Entrance')
yield ('Catfish Descent', inverted and 'Dark Death Mountain' or 'Dark Death Mountain (Top)', 'Catfish')
yield ('Hammer Pegs River Clip Spot', 'East Dark World', 'Hammer Peg Area')
yield ('Dark Lake Hylia Ledge Clip Spot', 'East Dark World', 'Dark Lake Hylia Ledge')
yield ('Dark Desert Cliffs Clip Spot', 'South Dark World', 'Dark Desert')
if not inverted:
yield ('Dark Death Mountain Descent', 'Dark Death Mountain (West Bottom)', 'West Dark World')
yield ('Ganons Tower Ascent', 'Dark Death Mountain (West Bottom)', 'Dark Death Mountain (Top)') # This only gets you to the GT entrance
yield ('Dark Death Mountain Glitched Bridge', 'Dark Death Mountain (West Bottom)', 'Dark Death Mountain (Top)')
yield ('Turtle Rock (Top) Clip Spot', 'Dark Death Mountain (Top)', 'Turtle Rock (Top)')
else:
yield ('Dark Desert Teleporter Clip Spot', 'Dark Desert', 'Dark Desert Ledge')
def get_glitched_speed_drops_dw(inverted = False):
"""
Dark World drop-down ledges that require glitched speed.
"""
yield ('Dark Death Mountain Ledge Clip Spot', inverted and 'Dark Death Mountain' or 'Dark Death Mountain (Top)', 'Dark Death Mountain Ledge')
def get_mirror_clip_spots_dw():
"""
Mirror shenanigans that are in logic even if the player is a bunny.
"""
yield ('Dark Death Mountain Offset Mirror', 'Dark Death Mountain (West Bottom)', 'East Dark World')
yield ('Dark Death Mountain Bunny Descent Mirror Spot', 'Dark Death Mountain (West Bottom)', 'Dark Death Mountain Bunny Descent Area')
yield ('West Dark World Bunny Descent', 'Dark Death Mountain Bunny Descent Area', 'West Dark World')
yield ('Dark Death Mountain (East Bottom) Jump', 'Dark Death Mountain Bunny Descent Area', 'Dark Death Mountain (East Bottom)')
def get_mirror_clip_spots_lw():
"""
Inverted mirror shenanigans in logic even if the player is a bunny.
"""
yield ('Death Mountain Bunny Descent Mirror Spot', 'Death Mountain', 'Death Mountain Bunny Descent Area')
yield ('Light World Bunny Descent', 'Death Mountain Bunny Descent Area', 'Light World')
yield ('East Death Mountain (Bottom) Jump', 'Death Mountain Bunny Descent Area', 'East Death Mountain (Bottom)')
def get_invalid_bunny_revival_dungeons():
"""
Dungeon regions that can't be bunny revived from.
"""
yield 'Tower of Hera (Bottom)'
yield 'Swamp Palace (Entrance)'
yield 'Turtle Rock (Entrance)'
yield 'Sanctuary'
def overworld_glitches_rules(world, player):
# Boots-accessible locations.
create_owg_connections(player, world, get_boots_clip_exits_lw(world.mode[player] == 'inverted'), lambda state: state.can_boots_clip_lw(player))
create_owg_connections(player, world, get_boots_clip_exits_dw(world.mode[player] == 'inverted'), lambda state: state.can_boots_clip_dw(player))
if world.mode[player] != 'inverted':
create_owg_connections(player, world, [('Ice Palace Clip', 'South Dark World', 'Dark Lake Hylia Central Island')], lambda state: state.can_boots_clip_dw(player) and state.has('Flippers', player))
# Glitched speed drops.
create_owg_connections(player, world, get_glitched_speed_drops_dw(world.mode[player] == 'inverted'), lambda state: state.can_get_glitched_speed_dw(player))
# Dark Death Mountain Ledge Clip Spot also accessible with mirror.
if world.mode[player] != 'inverted':
add_alternate_rule(world.get_entrance('Dark Death Mountain Ledge Clip Spot', player), lambda state: state.has_Mirror(player))
# Mirror clip spots.
if world.mode[player] != 'inverted':
create_owg_connections(player, world, get_mirror_clip_spots_dw(), lambda state: state.has_Mirror(player))
else:
create_owg_connections(player, world, get_mirror_clip_spots_lw(), lambda state: state.has_Mirror(player))
# Regions that require the boots and some other stuff.
if world.mode[player] != 'inverted':
world.get_entrance('Turtle Rock Teleporter', player).access_rule = lambda state: (state.can_boots_clip_lw(player) or state.can_lift_heavy_rocks(player)) and state.has('Hammer', player)
add_alternate_rule(world.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Moon Pearl', player) or state.has_Boots(player))
else:
add_alternate_rule(world.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Moon Pearl', player))
world.get_entrance('Dark Desert Teleporter', player).access_rule = lambda state: (state.has('Flute', player) or state.has_Boots(player)) and state.can_lift_heavy_rocks(player)
add_alternate_rule(world.get_entrance('Catfish Exit Rock', player), lambda state: state.can_boots_clip_dw(player))
add_alternate_rule(world.get_entrance('East Dark World Broken Bridge Pass', player), lambda state: state.can_boots_clip_dw(player))
# Zora's Ledge via waterwalk setup.
add_alternate_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has_Boots(player))
def add_alternate_rule(entrance, rule):
old_rule = entrance.access_rule
entrance.access_rule = lambda state: old_rule(state) or rule(state)
def create_owg_connections(player, world, connections, rule):
for entrance, parent_region, target_region in connections:
#@todo: remove - making sure I didn't leave an entrance
for region in world.regions:
for exit in region.exits:
if exit.name == entrance and exit.player == player:
raise RuntimeError('Redefining an entrance %s:%d' % (entrance, player))
parent = world.get_region(parent_region, player)
target = world.get_region(target_region, player)
connection = Entrance(player, entrance, parent)
parent.exits.append(connection)
connection.connect(target)
connection.access_rule = rule

View File

@@ -14,8 +14,7 @@ def create_regions(world, player):
'Sanctuary', 'Sanctuary Grave', 'Death Mountain Entrance Rock', 'Flute Spot 1', 'Dark Desert Teleporter', 'East Hyrule Teleporter', 'South Hyrule Teleporter', 'Kakariko Teleporter', 'Sanctuary', 'Sanctuary Grave', 'Death Mountain Entrance Rock', 'Flute Spot 1', 'Dark Desert Teleporter', 'East Hyrule Teleporter', 'South Hyrule Teleporter', 'Kakariko Teleporter',
'Elder House (East)', 'Elder House (West)', 'North Fairy Cave', 'North Fairy Cave Drop', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Tavern (Front)', 'Elder House (East)', 'Elder House (West)', 'North Fairy Cave', 'North Fairy Cave Drop', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Tavern (Front)',
'Bush Covered House', 'Light World Bomb Hut', 'Kakariko Shop', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', 'Cave Shop (Lake Hylia)', 'Waterfall of Wishing', 'Hyrule Castle Main Gate', 'Bush Covered House', 'Light World Bomb Hut', 'Kakariko Shop', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', 'Cave Shop (Lake Hylia)', 'Waterfall of Wishing', 'Hyrule Castle Main Gate',
'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Top of Pyramid', 'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Top of Pyramid']),
'Light World DMA Clip Spot', 'Death Mountain Return Ledge Clip Spot', 'Desert Northern Cliffs', 'Lake Hylia Island Clip Spot', 'Bat Cave River Clip Spot', 'Bombos Tablet Clip Spot', 'Cave 45 Clip Spot']),
create_lw_region(player, 'Death Mountain Entrance', None, ['Old Man Cave (West)', 'Death Mountain Entrance Drop']), create_lw_region(player, 'Death Mountain Entrance', None, ['Old Man Cave (West)', 'Death Mountain Entrance Drop']),
create_lw_region(player, 'Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Teleporter']), create_lw_region(player, 'Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Teleporter']),
create_cave_region(player, 'Blinds Hideout', 'a bounty of five items', ["Blind\'s Hideout - Top", create_cave_region(player, 'Blinds Hideout', 'a bounty of five items', ["Blind\'s Hideout - Top",
@@ -118,7 +117,7 @@ def create_regions(world, player):
create_cave_region(player, 'Old Man Cave', 'a connector', ['Old Man'], ['Old Man Cave Exit (East)', 'Old Man Cave Exit (West)']), create_cave_region(player, 'Old Man Cave', 'a connector', ['Old Man'], ['Old Man Cave Exit (East)', 'Old Man Cave Exit (West)']),
create_cave_region(player, 'Old Man House', 'a connector', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']), create_cave_region(player, 'Old Man House', 'a connector', None, ['Old Man House Exit (Bottom)', 'Old Man House Front to Back']),
create_cave_region(player, 'Old Man House Back', 'a connector', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']), create_cave_region(player, 'Old Man House Back', 'a connector', None, ['Old Man House Exit (Top)', 'Old Man House Back to Front']),
create_lw_region(player, 'Death Mountain', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Broken Bridge (West)', 'Death Mountain Teleporter', 'Death Mountain Glitched Bridge', 'Graveyard Ledge Clip Spot', 'Hera Ascent', 'Death Mountain Descent']), create_lw_region(player, 'Death Mountain', None, ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Broken Bridge (West)', 'Death Mountain Teleporter']),
create_cave_region(player, 'Death Mountain Return Cave', 'a connector', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']), create_cave_region(player, 'Death Mountain Return Cave', 'a connector', None, ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)']),
create_lw_region(player, 'Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)']), create_lw_region(player, 'Death Mountain Return Ledge', None, ['Death Mountain Return Ledge Drop', 'Death Mountain Return Cave (West)']),
create_cave_region(player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']), create_cave_region(player, 'Spectacle Rock Cave (Top)', 'a connector', ['Spectacle Rock Cave'], ['Spectacle Rock Cave Drop', 'Spectacle Rock Cave Exit (Top)']),
@@ -137,7 +136,8 @@ def create_regions(world, player):
['Paradox Cave Push Block', 'Paradox Cave Bomb Jump']), ['Paradox Cave Push Block', 'Paradox Cave Bomb Jump']),
create_cave_region(player, 'Paradox Cave', 'a connector', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']), create_cave_region(player, 'Paradox Cave', 'a connector', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']),
create_cave_region(player, 'Light World Death Mountain Shop', 'a common shop'), create_cave_region(player, 'Light World Death Mountain Shop', 'a common shop'),
create_lw_region(player, 'East Death Mountain (Top)', None, ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'Turtle Rock Teleporter', 'Fairy Ascension Ledge', 'Floating Island Clip Spot', 'Zora Descent Clip Spot']), create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Cave', 'Spiral Cave Ledge Drop']), create_lw_region(player, 'East Death Mountain (Top)', None, ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'Turtle Rock Teleporter', 'Fairy Ascension Ledge']),
create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Cave', 'Spiral Cave Ledge Drop']),
create_cave_region(player, 'Spiral Cave (Top)', 'a connector', ['Spiral Cave'], ['Spiral Cave (top to bottom)', 'Spiral Cave Exit (Top)']), create_cave_region(player, 'Spiral Cave (Top)', 'a connector', ['Spiral Cave'], ['Spiral Cave (top to bottom)', 'Spiral Cave Exit (Top)']),
create_cave_region(player, 'Spiral Cave (Bottom)', 'a connector', None, ['Spiral Cave Exit']), create_cave_region(player, 'Spiral Cave (Bottom)', 'a connector', None, ['Spiral Cave Exit']),
create_lw_region(player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Drop', 'Fairy Ascension Cave (Bottom)']), create_lw_region(player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Drop', 'Fairy Ascension Cave (Bottom)']),
@@ -145,21 +145,21 @@ def create_regions(world, player):
create_cave_region(player, 'Fairy Ascension Cave (Drop)', 'a connector', None, ['Fairy Ascension Cave Pots']), create_cave_region(player, 'Fairy Ascension Cave (Drop)', 'a connector', None, ['Fairy Ascension Cave Pots']),
create_cave_region(player, 'Fairy Ascension Cave (Top)', 'a connector', None, ['Fairy Ascension Cave Exit (Top)', 'Fairy Ascension Cave Drop']), create_cave_region(player, 'Fairy Ascension Cave (Top)', 'a connector', None, ['Fairy Ascension Cave Exit (Top)', 'Fairy Ascension Cave Drop']),
create_lw_region(player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)']), create_lw_region(player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)']),
create_lw_region(player, 'Death Mountain (Top)', ['Ether Tablet'], ['East Death Mountain (Top)', 'Tower of Hera', 'Death Mountain Drop', 'Spectacle Rock Clip Spot']), create_lw_region(player, 'Spectacle Rock', ['Spectacle Rock'], ['Spectacle Rock Drop']), create_lw_region(player, 'Death Mountain (Top)', ['Ether Tablet'], ['East Death Mountain (Top)', 'Tower of Hera', 'Death Mountain Drop']),
create_lw_region(player, 'Spectacle Rock', ['Spectacle Rock'], ['Spectacle Rock Drop']),
create_dungeon_region(player, 'Tower of Hera (Bottom)', 'Tower of Hera', ['Tower of Hera - Basement Cage', 'Tower of Hera - Map Chest'], ['Tower of Hera Small Key Door', 'Tower of Hera Big Key Door', 'Tower of Hera Exit']), create_dungeon_region(player, 'Tower of Hera (Bottom)', 'Tower of Hera', ['Tower of Hera - Basement Cage', 'Tower of Hera - Map Chest'], ['Tower of Hera Small Key Door', 'Tower of Hera Big Key Door', 'Tower of Hera Exit']),
create_dungeon_region(player, 'Tower of Hera (Basement)', 'Tower of Hera', ['Tower of Hera - Big Key Chest']), create_dungeon_region(player, 'Tower of Hera (Basement)', 'Tower of Hera', ['Tower of Hera - Big Key Chest']),
create_dungeon_region(player, 'Tower of Hera (Top)', 'Tower of Hera', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Boss', 'Tower of Hera - Prize']), create_dungeon_region(player, 'Tower of Hera (Top)', 'Tower of Hera', ['Tower of Hera - Compass Chest', 'Tower of Hera - Big Chest', 'Tower of Hera - Boss', 'Tower of Hera - Prize']),
create_dw_region(player, 'East Dark World', ['Pyramid'], ['Pyramid Fairy', 'South Dark World Bridge', 'Palace of Darkness', 'Dark Lake Hylia Drop (East)', 'Dark Lake Hylia Teleporter', create_dw_region(player, 'East Dark World', ['Pyramid'], ['Pyramid Fairy', 'South Dark World Bridge', 'Palace of Darkness', 'Dark Lake Hylia Drop (East)', 'Dark Lake Hylia Teleporter',
'Hyrule Castle Ledge Mirror Spot', 'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Pyramid Hole', 'Northeast Dark World Broken Bridge Pass', 'Hyrule Castle Ledge Mirror Spot', 'Dark Lake Hylia Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Pyramid Hole', 'Northeast Dark World Broken Bridge Pass',]),
'Hammer Pegs River Clip Spot', 'Dark Lake Hylia Ledge Clip Spot']),
create_dw_region(player, 'Catfish', ['Catfish'], ['Catfish Exit Rock']), create_dw_region(player, 'Catfish', ['Catfish'], ['Catfish Exit Rock']),
create_dw_region(player, 'Northeast Dark World', None, ['West Dark World Gap', 'Dark World Potion Shop', 'East Dark World Broken Bridge Pass', 'Catfish Entrance Rock']), create_dw_region(player, 'Northeast Dark World', None, ['West Dark World Gap', 'Dark World Potion Shop', 'East Dark World Broken Bridge Pass', 'Catfish Entrance Rock']),
create_cave_region(player, 'Palace of Darkness Hint', 'a storyteller'), create_cave_region(player, 'Palace of Darkness Hint', 'a storyteller'),
create_cave_region(player, 'East Dark World Hint', 'a storyteller'), create_cave_region(player, 'East Dark World Hint', 'a storyteller'),
create_dw_region(player, 'South Dark World', ['Stumpy', 'Digging Game'], ['Dark Lake Hylia Drop (South)', 'Hype Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock', 'Maze Race Mirror Spot', create_dw_region(player, 'South Dark World', ['Stumpy', 'Digging Game'], ['Dark Lake Hylia Drop (South)', 'Hype Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock', 'Maze Race Mirror Spot',
'Cave 45 Mirror Spot', 'East Dark World Bridge', 'Big Bomb Shop', 'Archery Game', 'Bonk Fairy (Dark)', 'Dark Lake Hylia Shop', 'Cave 45 Mirror Spot', 'East Dark World Bridge', 'Big Bomb Shop', 'Archery Game', 'Bonk Fairy (Dark)', 'Dark Lake Hylia Shop',
'Bombos Tablet Mirror Spot', 'Dark Desert Cliffs Clip Spot']), 'Bombos Tablet Mirror Spot']),
create_lw_region(player, 'Bombos Tablet Ledge', ['Bombos Tablet']), create_lw_region(player, 'Bombos Tablet Ledge', ['Bombos Tablet']),
create_cave_region(player, 'Big Bomb Shop', 'the bomb shop'), create_cave_region(player, 'Big Bomb Shop', 'the bomb shop'),
create_cave_region(player, 'Archery Game', 'a game of skill'), create_cave_region(player, 'Archery Game', 'a game of skill'),
@@ -171,8 +171,7 @@ def create_regions(world, player):
create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left', create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left',
'Hype Cave - Bottom', 'Hype Cave - Generous Guy']), 'Hype Cave - Bottom', 'Hype Cave - Generous Guy']),
create_dw_region(player, 'West Dark World', ['Frog'], ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Graveyard Ledge Mirror Spot', 'Kings Grave Mirror Spot', 'Bumper Cave Entrance Rock', create_dw_region(player, 'West Dark World', ['Frog'], ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Graveyard Ledge Mirror Spot', 'Kings Grave Mirror Spot', 'Bumper Cave Entrance Rock',
'Skull Woods Forest', 'Village of Outcasts Pegs', 'Village of Outcasts Eastern Rocks', 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Dark World Lumberjack Shop', 'Skull Woods Forest', 'Village of Outcasts Pegs', 'Village of Outcasts Eastern Rocks', 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Dark World Lumberjack Shop']),
'Dark World DMA Clip Spot', 'Bumper Cave Ledge Clip Spot']),
create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop']), create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop']),
create_dw_region(player, 'Hammer Peg Area', ['Dark Blacksmith Ruins'], ['Bat Cave Drop Ledge Mirror Spot', 'Dark World Hammer Peg Cave', 'Peg Area Rocks']), create_dw_region(player, 'Hammer Peg Area', ['Dark Blacksmith Ruins'], ['Bat Cave Drop Ledge Mirror Spot', 'Dark World Hammer Peg Cave', 'Peg Area Rocks']),
create_dw_region(player, 'Bumper Cave Entrance', None, ['Bumper Cave (Bottom)', 'Bumper Cave Entrance Mirror Spot', 'Bumper Cave Entrance Drop']), create_dw_region(player, 'Bumper Cave Entrance', None, ['Bumper Cave (Bottom)', 'Bumper Cave Entrance Mirror Spot', 'Bumper Cave Entrance Drop']),
@@ -197,9 +196,9 @@ def create_regions(world, player):
'Desert Palace Entrance (North) Mirror Spot', 'Dark Desert Hint', 'Dark Desert Fairy']), 'Desert Palace Entrance (North) Mirror Spot', 'Dark Desert Hint', 'Dark Desert Fairy']),
create_cave_region(player, 'Mire Shed', 'a cave with two chests', ['Mire Shed - Left', 'Mire Shed - Right']), create_cave_region(player, 'Mire Shed', 'a cave with two chests', ['Mire Shed - Left', 'Mire Shed - Right']),
create_cave_region(player, 'Dark Desert Hint', 'a storyteller'), create_cave_region(player, 'Dark Desert Hint', 'a storyteller'),
create_dw_region(player, 'Dark Death Mountain (West Bottom)', None, ['Spike Cave', 'Spectacle Rock Mirror Spot', 'Dark Death Mountain Fairy', 'Ganons Tower Ascent', 'Dark Death Mountain Glitched Bridge', 'Dark Death Mountain Bunny Descent Mirror Spot', 'Dark Death Mountain Offset Mirror', 'Dark Death Mountain Descent']), create_dw_region(player, 'Dark Death Mountain (West Bottom)', None, ['Spike Cave', 'Spectacle Rock Mirror Spot', 'Dark Death Mountain Fairy']),
create_dw_region(player, 'Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Dark Death Mountain Drop (West)', 'Ganons Tower', 'Superbunny Cave (Top)', create_dw_region(player, 'Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Dark Death Mountain Drop (West)', 'Ganons Tower', 'Superbunny Cave (Top)',
'Hookshot Cave', 'East Death Mountain (Top) Mirror Spot', 'Turtle Rock', 'Catfish Descent', 'Dark Death Mountain Ledge Clip Spot', 'Turtle Rock (Top) Clip Spot']), 'Hookshot Cave', 'East Death Mountain (Top) Mirror Spot', 'Turtle Rock']),
create_dw_region(player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)', 'Mimic Cave Mirror Spot', 'Spiral Cave Mirror Spot']), create_dw_region(player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)', 'Mimic Cave Mirror Spot', 'Spiral Cave Mirror Spot']),
create_dw_region(player, 'Dark Death Mountain Isolated Ledge', None, ['Isolated Ledge Mirror Spot', 'Turtle Rock Isolated Ledge Entrance']), create_dw_region(player, 'Dark Death Mountain Isolated Ledge', None, ['Isolated Ledge Mirror Spot', 'Turtle Rock Isolated Ledge Entrance']),
create_dw_region(player, 'Dark Death Mountain (East Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Fairy Ascension Mirror Spot']), create_dw_region(player, 'Dark Death Mountain (East Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Fairy Ascension Mirror Spot']),
@@ -295,7 +294,8 @@ def create_regions(world, player):
create_cave_region(player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']), create_cave_region(player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']),
create_cave_region(player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']), create_cave_region(player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']),
create_dw_region(player, 'Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop']), create_dw_region(player, 'Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop']),
create_dw_region(player, 'Dark Death Mountain Bunny Descent Area', None, ['West Dark World Bunny Descent', 'Dark Death Mountain (East Bottom) Jump']), create_lw_region(player, 'Desert Northern Cliffs'),
create_dw_region(player, 'Dark Death Mountain Bunny Descent Area')
] ]
for region_name, (room_id, shopkeeper, replaceable) in shop_table.items(): for region_name, (room_id, shopkeeper, replaceable) in shop_table.items():

124
Rules.py
View File

@@ -1,7 +1,8 @@
import collections import collections
import logging import logging
import OWGSets import OverworldGlitchRules
from BaseClasses import CollectionState, RegionType from BaseClasses import RegionType
from OverworldGlitchRules import overworld_glitches_rules
def set_rules(world, player): def set_rules(world, player):
@@ -43,6 +44,7 @@ def set_rules(world, player):
# Initially setting no_glitches_rules to set the baseline rules for some # Initially setting no_glitches_rules to set the baseline rules for some
# entrances. The overworld_glitches_rules set is primarily additive. # entrances. The overworld_glitches_rules set is primarily additive.
no_glitches_rules(world, player) no_glitches_rules(world, player)
fake_flipper_rules(world, player)
overworld_glitches_rules(world, player) overworld_glitches_rules(world, player)
else: else:
raise NotImplementedError('Not implemented yet') raise NotImplementedError('Not implemented yet')
@@ -899,7 +901,7 @@ def no_glitches_rules(world, player):
set_rule(world.get_entrance('Northeast Light World Warp', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player)) # can be fake flippered to set_rule(world.get_entrance('Northeast Light World Warp', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player)) # can be fake flippered to
set_rule(world.get_entrance('Hobo Bridge', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player)) set_rule(world.get_entrance('Hobo Bridge', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player))
set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player))
set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Flippers', player) and (state.has('Hammer', player) or state.can_lift_rocks(player))) set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Flippers', player))
set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has('Flippers', player))
add_rule(world.get_entrance('Ganons Tower (Hookshot Room)', player), lambda state: state.has('Hookshot', player) or state.has_Boots(player)) add_rule(world.get_entrance('Ganons Tower (Hookshot Room)', player), lambda state: state.has('Hookshot', player) or state.has_Boots(player))
@@ -909,9 +911,30 @@ def no_glitches_rules(world, player):
add_rule(world.get_location(location, player), lambda state: state.has('Hookshot', player)) add_rule(world.get_location(location, player), lambda state: state.has('Hookshot', player))
set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: False) # no glitches does not require block override set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: False) # no glitches does not require block override
forbid_bomb_jump_requirements(world, player) forbid_bomb_jump_requirements(world, player)
forbid_overworld_glitches(world, player) add_conditional_lamps(world, player)
add_conditional_lamps(world, player)
def fake_flipper_rules(world, player):
if world.mode != 'inverted':
set_rule(world.get_entrance('Zoras River', player), lambda state: True)
set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: True)
set_rule(world.get_entrance('Hobo Bridge', player), lambda state: True)
set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player))
set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player) and (state.has('Hammer', player) or state.can_lift_rocks(player)))
set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has_Pearl(player))
else:
set_rule(world.get_entrance('Zoras River', player), lambda state: state.has_Pearl(player))
set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has_Pearl(player))
set_rule(world.get_entrance('Lake Hylia Island Pier', player), lambda state: state.has_Pearl(player))
set_rule(world.get_entrance('Lake Hylia Warp', player), lambda state: state.has_Pearl(player))
set_rule(world.get_entrance('Northeast Light World Warp', player), lambda state: state.has_Pearl(player))
set_rule(world.get_entrance('Hobo Bridge', player), lambda state: state.has_Pearl(player))
set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player))
set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: True)
set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: True)
set_rule(world.get_entrance('East Dark World Pier', player), lambda state: True) #todo: Ice Palace exit
def forbid_bomb_jump_requirements(world, player): def forbid_bomb_jump_requirements(world, player):
DMs_room_chests = ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', 'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right'] DMs_room_chests = ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', 'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right']
for location in DMs_room_chests: for location in DMs_room_chests:
@@ -967,51 +990,6 @@ def add_conditional_lamps(world, player):
add_lamp_requirement(world.get_entrance('Sewers Back Door', player), player) add_lamp_requirement(world.get_entrance('Sewers Back Door', player), player)
add_lamp_requirement(world.get_entrance('Throne Room', player), player) add_lamp_requirement(world.get_entrance('Throne Room', player), player)
def overworld_glitches_rules(world, player):
# Spots that are immediately accessible.
for entrance in OWGSets.get_immediately_accessible_entrances(world, player):
set_rule(world.get_entrance(entrance, player), lambda state: True)
# Boots-accessible locations.
for entrance in OWGSets.get_boots_clip_exits_lw(world.mode == 'inverted'):
set_rule(world.get_entrance(entrance, player), lambda state: state.can_boots_clip_lw(player))
for entrance in OWGSets.get_boots_clip_exits_dw(world.mode == 'inverted'):
set_rule(world.get_entrance(entrance, player), lambda state: state.can_boots_clip_dw(player))
# Glitched speed drops.
for drop in OWGSets.get_glitched_speed_drops_dw():
set_rule(world.get_entrance(drop, player), lambda state: state.can_get_glitched_speed_dw(player))
# Dark Death Mountain Ledge Clip Spot also accessible with mirror.
if world.mode != 'inverted':
add_rule(world.get_entrance('Dark Death Mountain Ledge Clip Spot', player), lambda state: state.has_Mirror(player), 'or')
# Mirror clip spots.
if world.mode != 'inverted':
for clip_spot in OWGSets.get_mirror_clip_spots_dw():
set_rule(world.get_entrance(clip_spot, player), lambda state: state.has_Mirror(player))
else:
for clip_spot in OWGSets.get_mirror_clip_spots_lw():
set_rule(world.get_entrance(clip_spot, player), lambda state: state.has_Mirror(player))
# Locations that you can superbunny mirror into, but need a sword to clear.
for superbunny_mirror_weapon_region in OWGSets.get_sword_required_superbunny_mirror_regions():
region = world.get_region(superbunny_mirror_weapon_region, player)
if check_is_dark_world(region):
for spot in region.locations:
add_rule(world.get_location(spot, player), lambda state: state.can_superbunny_mirror_with_sword(player), 'or')
# Regions that require the boots and some other stuff.
if world.mode != 'inverted':
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: (state.has('Ocarina', player) or state.can_boots_clip_lw(player)) and state.can_lift_heavy_rocks(player))
set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: (state.can_boots_clip_lw(player) or state.can_lift_heavy_rocks(player)) and state.has('Hammer', player))
add_rule(world.get_entrance('Catfish Exit Rock', player), lambda state: state.can_boots_clip_dw(player), 'or')
add_rule(world.get_entrance('East Dark World Broken Bridge Pass', player), lambda state: state.can_boots_clip_dw(player), 'or')
else:
add_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has_Boots(player) and state.can_lift_rocks(player), 'or')
# Zora's Ledge via waterwalk setup.
add_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has_Boots(player), 'or')
def open_rules(world, player): def open_rules(world, player):
# softlock protection as you can reach the sewers small key door with a guard drop key # softlock protection as you can reach the sewers small key door with a guard drop key
forbid_item(world.get_location('Hyrule Castle - Boomerang Chest', player), 'Small Key (Escape)', player) forbid_item(world.get_location('Hyrule Castle - Boomerang Chest', player), 'Small Key (Escape)', player)
@@ -1608,12 +1586,17 @@ def set_bunny_rules(world, player):
if world.logic == 'owglitches': if world.logic == 'owglitches':
if region.name == 'Swamp Palace (Entrance)': if region.name == 'Swamp Palace (Entrance)':
return lambda state: state.has_Pearl(player) return lambda state: state.has_Pearl(player)
if region.name in OWGSets.get_invalid_bunny_revival_dungeons(): if region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons():
return lambda state: state.has_Mirror(player) or state.has_Pearl(player) return lambda state: state.has_Mirror(player) or state.has_Pearl(player)
if region.type == RegionType.Dungeon: if region.type == RegionType.Dungeon:
return lambda state: True return lambda state: True
if (((location is None or location.name not in OWGSets.get_superbunny_accessible_locations()) if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions():
or (connecting_entrance is not None and connecting_entrance.name in OWGSets.get_invalid_bunny_revival_dungeons())) return lambda state: state.has_Mirror(player) and state.has_sword(player) or state.has_Pearl(player)
if (region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions()
or location is not None and location.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_locations()):
return lambda state: state.has_Mirror(player) and state.has_Boots(player) or state.has_Pearl(player)
if (((location is None or location.name not in OverworldGlitchRules.get_superbunny_accessible_locations())
or (connecting_entrance is not None and connecting_entrance.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons()))
and not region.is_light_world): and not region.is_light_world):
return lambda state: state.has_Pearl(player) return lambda state: state.has_Pearl(player)
else: else:
@@ -1642,10 +1625,13 @@ def set_bunny_rules(world, player):
seen.add(new_region) seen.add(new_region)
if not new_region.is_light_world: if not new_region.is_light_world:
# For OWG, establish superbunny and revival rules. # For OWG, establish superbunny and revival rules.
if world.logic == 'owglitches' and entrance.name not in OWGSets.get_invalid_mirror_bunny_entrances_dw(): if world.logic == 'owglitches' and entrance.name not in OverworldGlitchRules.get_invalid_mirror_bunny_entrances_dw():
if new_region.name == 'Two Brothers House': if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions():
possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_sword(player))
elif (region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions()
or location is not None and location.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_locations()):
possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_Boots(player)) possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_Boots(player))
if location is not None and location.name in OWGSets.get_superbunny_accessible_locations(): elif location is not None and location.name in OverworldGlitchRules.get_superbunny_accessible_locations():
if new_region.name == 'Superbunny Cave (Bottom)' or region.name == 'Kakariko Well (top)': if new_region.name == 'Superbunny Cave (Bottom)' or region.name == 'Kakariko Well (top)':
possible_options.append(lambda state: path_to_access_rule(new_path, entrance)) possible_options.append(lambda state: path_to_access_rule(new_path, entrance))
else: else:
@@ -1678,19 +1664,20 @@ def set_bunny_rules(world, player):
if entrance.player == player and entrance.connected_region.is_dark_world: if entrance.player == player and entrance.connected_region.is_dark_world:
if world.logic == 'owglitches': if world.logic == 'owglitches':
if entrance.connected_region.type == RegionType.Dungeon: if entrance.connected_region.type == RegionType.Dungeon:
if entrance.parent_region.type != RegionType.Dungeon and entrance.connected_region.name in OWGSets.get_invalid_bunny_revival_dungeons(): if entrance.parent_region.type != RegionType.Dungeon and entrance.connected_region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons():
add_rule(entrance, get_rule_to_add(entrance.connected_region, None, entrance)) add_rule(entrance, get_rule_to_add(entrance.connected_region, None, entrance))
continue continue
if entrance.connected_region.name == 'Turtle Rock (Entrance)': if entrance.connected_region.name == 'Turtle Rock (Entrance)':
add_rule(world.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance)) add_rule(world.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance))
for location in entrance.connected_region.locations: for location in entrance.connected_region.locations:
if world.logic == 'owglitches' and entrance.name in OWGSets.get_invalid_mirror_bunny_entrances_dw(): if world.logic == 'owglitches' and entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances_dw():
add_rule(location, get_rule_to_add(entrance.connected_region, location, entrance)) add_rule(location, get_rule_to_add(entrance.connected_region, location, entrance))
continue continue
if location.name in bunny_accessible_locations: if location.name in bunny_accessible_locations:
continue continue
add_rule(location, get_rule_to_add(entrance.connected_region, location)) add_rule(location, get_rule_to_add(entrance.connected_region, location))
#todo: combine this with set_bunny_rules
def set_inverted_bunny_rules(world, player): def set_inverted_bunny_rules(world, player):
# regions for the exits of multi-entrace caves/drops that bunny cannot pass # regions for the exits of multi-entrace caves/drops that bunny cannot pass
@@ -1713,12 +1700,12 @@ def set_inverted_bunny_rules(world, player):
if world.logic == 'owglitches': if world.logic == 'owglitches':
if region.name == 'Swamp Palace (Entrance)': if region.name == 'Swamp Palace (Entrance)':
return lambda state: state.has_Pearl(player) return lambda state: state.has_Pearl(player)
if region.name in OWGSets.get_invalid_bunny_revival_dungeons(): if region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons():
return lambda state: state.has_Mirror(player) or state.has_Pearl(player) return lambda state: state.has_Mirror(player) or state.has_Pearl(player)
if region.type == RegionType.Dungeon: if region.type == RegionType.Dungeon:
return lambda state: True return lambda state: True
if (((location is None or location.name not in OWGSets.get_superbunny_accessible_locations()) if (((location is None or location.name not in OverworldGlitchRules.get_superbunny_accessible_locations())
or (connecting_entrance is not None and connecting_entrance.name in OWGSets.get_invalid_bunny_revival_dungeons())) or (connecting_entrance is not None and connecting_entrance.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons()))
and not region.is_dark_world): and not region.is_dark_world):
return lambda state: state.has_Pearl(player) return lambda state: state.has_Pearl(player)
else: else:
@@ -1747,10 +1734,13 @@ def set_inverted_bunny_rules(world, player):
seen.add(new_region) seen.add(new_region)
if not new_region.is_dark_world: if not new_region.is_dark_world:
# For OWG, establish superbunny and revival rules. # For OWG, establish superbunny and revival rules.
if world.logic == 'owglitches' and entrance.name not in OWGSets.get_invalid_mirror_bunny_entrances_lw(): if world.logic == 'owglitches' and entrance.name not in OverworldGlitchRules.get_invalid_mirror_bunny_entrances_lw():
if new_region.name == 'Two Brothers House': if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions():
possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_sword(player))
elif (region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions()
or location is not None and location.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_locations()):
possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_Boots(player)) possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has_Mirror(player) and state.has_Boots(player))
if location is not None and location.name in OWGSets.get_superbunny_accessible_locations(): elif location is not None and location.name in OverworldGlitchRules.get_superbunny_accessible_locations():
if new_region.name == 'Superbunny Cave (Bottom)' or region.name == 'Kakariko Well (top)': if new_region.name == 'Superbunny Cave (Bottom)' or region.name == 'Kakariko Well (top)':
possible_options.append(lambda state: path_to_access_rule(new_path, entrance)) possible_options.append(lambda state: path_to_access_rule(new_path, entrance))
else: else:
@@ -1784,13 +1774,13 @@ def set_inverted_bunny_rules(world, player):
if entrance.player == player and entrance.connected_region.is_light_world: if entrance.player == player and entrance.connected_region.is_light_world:
if world.logic == 'owglitches': if world.logic == 'owglitches':
if entrance.connected_region.type == RegionType.Dungeon: if entrance.connected_region.type == RegionType.Dungeon:
if entrance.parent_region.type != RegionType.Dungeon and entrance.connected_region.name in OWGSets.get_invalid_bunny_revival_dungeons(): if entrance.parent_region.type != RegionType.Dungeon and entrance.connected_region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons():
add_rule(entrance, get_rule_to_add(entrance.connected_region, None, entrance)) add_rule(entrance, get_rule_to_add(entrance.connected_region, None, entrance))
continue continue
if entrance.connected_region.name == 'Turtle Rock (Entrance)': if entrance.connected_region.name == 'Turtle Rock (Entrance)':
add_rule(world.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance)) add_rule(world.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance))
for location in entrance.connected_region.locations: for location in entrance.connected_region.locations:
if world.logic == 'owglitches' and entrance.name in OWGSets.get_invalid_mirror_bunny_entrances_lw(): if world.logic == 'owglitches' and entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances_lw():
add_rule(location, get_rule_to_add(entrance.connected_region, location, entrance)) add_rule(location, get_rule_to_add(entrance.connected_region, location, entrance))
continue continue
if location.name in bunny_accessible_locations: if location.name in bunny_accessible_locations: