From 8c5a4be4802a831b6b265606295ed0d2c8f8b467 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 22 Jun 2021 13:04:37 -0600 Subject: [PATCH] Ranged crystal switch logic tweaked Couple of minor bugs fixed --- DoorShuffle.py | 15 +++++++++------ Doors.py | 23 +++++++++++++---------- Dungeons.py | 3 ++- RELEASENOTES.md | 1 + Regions.py | 5 +++-- Rules.py | 14 +++++++++----- 6 files changed, 37 insertions(+), 24 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index be46bd74..ee38f00c 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -99,6 +99,7 @@ def link_doors_main(world, player): for portal in world.dungeon_portals[player]: connect_portal(portal, world, player) + fix_big_key_doors_with_ugly_smalls(world, player) if world.doorShuffle[player] == 'vanilla': for entrance, ext in open_edges: connect_two_way(world, entrance, ext, player) @@ -676,7 +677,6 @@ def find_entrance_region(portal): # paired_door.pair = False def within_dungeon(world, player): - fix_big_key_doors_with_ugly_smalls(world, player) add_inaccessible_doors(world, player) entrances_map, potentials, connections = determine_entrance_list(world, player) connections_tuple = (entrances_map, potentials, connections) @@ -930,7 +930,6 @@ def treat_split_as_whole_dungeon(split_dungeon, name, origin_list, world, player def cross_dungeon(world, player): - fix_big_key_doors_with_ugly_smalls(world, player) add_inaccessible_doors(world, player) entrances_map, potentials, connections = determine_entrance_list(world, player) connections_tuple = (entrances_map, potentials, connections) @@ -1617,13 +1616,15 @@ def reassign_key_doors(builder, world, player): else: room.delete(d.doorListPos) d.smallKey = False - elif d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal and not d.entranceFlag: - world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) + elif d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal: + if not d.entranceFlag: + world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) d.smallKey = False d.dest.smallKey = False queue.remove(d.dest) - elif d.type is DoorType.Normal and d not in flat_proposal and not d.entranceFlag: - world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) + elif d.type is DoorType.Normal and d not in flat_proposal: + if not d.entranceFlag: + world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) d.smallKey = False for dp in world.paired_doors[player]: if dp.door_a == d.name or dp.door_b == d.name: @@ -2294,6 +2295,8 @@ logical_connections = [ ('GT Double Switch Entry to Left Barrier - Orange', 'GT Double Switch Left'), ('GT Double Switch Entry to Ranged Switches', 'GT Double Switch Entry - Ranged Switches'), ('GT Double Switch Entry Ranged Switches Exit', 'GT Double Switch Entry'), + ('GT Double Switch Left to Crystal', 'GT Double Switch Left - Crystal'), + ('GT Double Switch Left Crystal Exit', 'GT Double Switch Left'), ('GT Double Switch Left to Entry Barrier - Orange', 'GT Double Switch Entry'), ('GT Double Switch Left to Entry Bypass', 'GT Double Switch Entry'), ('GT Double Switch Left to Pot Corners Bypass', 'GT Double Switch Pot Corners'), diff --git a/Doors.py b/Doors.py index cc13826e..b0979a5d 100644 --- a/Doors.py +++ b/Doors.py @@ -397,10 +397,10 @@ def create_doors(world, player): create_door(player, 'PoD Arena Landing to Right Barrier - Blue', Lgcl), create_door(player, 'PoD Arena Landing to North Barrier - Orange', Lgcl), create_door(player, 'PoD Arena Right to Landing Barrier - Blue', Lgcl), - create_door(player, 'PoD Arena Right to Ranged Crystal', Lgcl), - create_door(player, 'PoD Arena Right Ranged Crystal Exit', Lgcl), - create_door(player, 'PoD Arena Ledge to Ranged Crystal', Lgcl), - create_door(player, 'PoD Arena Ledge Ranged Crystal Exit', Lgcl), + create_door(player, 'PoD Arena Right to Ranged Crystal', Lgcl), # considered out of logic + create_door(player, 'PoD Arena Right Ranged Crystal Exit', Lgcl).no_exit(), # blocked here for pre-validate + create_door(player, 'PoD Arena Ledge to Ranged Crystal', Lgcl), # considered out of logic + create_door(player, 'PoD Arena Ledge Ranged Crystal Exit', Lgcl).no_exit(), # blocked here for pre-validate create_door(player, 'PoD Arena Ledge ES', Nrml).dir(Ea, 0x2a, Bot, High).pos(2), create_door(player, 'PoD Sexy Statue W', Nrml).dir(We, 0x2b, Mid, High).pos(3), create_door(player, 'PoD Sexy Statue NW', Nrml).dir(No, 0x2b, Left, High).trap(0x1).pos(2), @@ -875,7 +875,7 @@ def create_doors(world, player): create_door(player, 'Mire Left Bridge Down Stairs', Sprl).dir(Dn, 0xa2, 0, HTL).ss(A, 0x12, 0x00), create_door(player, 'Mire Fishbone E', Nrml).dir(Ea, 0xa1, Mid, High).pos(1), create_door(player, 'Mire Fishbone Blue Barrier', Lgcl), - create_door(player, 'Mire Fishbone Blue Barrier Bypass', Lgcl), + create_door(player, 'Mire Fishbone Blue Barrier Bypass', Lgcl).no_exit(), # considered out of logic create_door(player, 'Mire South Fish Blue Barrier', Lgcl), create_door(player, 'Mire Fishbone SE', Nrml).dir(So, 0xa1, Right, High).small_key().pos(0), create_door(player, 'Mire Spike Barrier NE', Nrml).dir(No, 0xb1, Right, High).small_key().pos(1), @@ -1116,16 +1116,18 @@ def create_doors(world, player): create_door(player, 'GT Double Switch NW', Nrml).dir(No, 0x9b, Left, High).pos(1).kill(), create_door(player, 'GT Double Switch Entry to Pot Corners Barrier - Orange', Lgcl), create_door(player, 'GT Double Switch Entry to Left Barrier - Orange', Lgcl), - create_door(player, 'GT Double Switch Entry to Ranged Switches', Lgcl), - create_door(player, 'GT Double Switch Entry Ranged Switches Exit', Lgcl), + create_door(player, 'GT Double Switch Entry to Ranged Switches', Lgcl), # considered out of logic + create_door(player, 'GT Double Switch Entry Ranged Switches Exit', Lgcl).no_exit(), # blocked here for reasons + create_door(player, 'GT Double Switch Left to Crystal', Lgcl), + create_door(player, 'GT Double Switch Left Crystal Exit', Lgcl), create_door(player, 'GT Double Switch Left to Entry Barrier - Orange', Lgcl), create_door(player, 'GT Double Switch Left to Pot Corners Bypass', Lgcl), create_door(player, 'GT Double Switch Left to Entry Bypass', Lgcl), - create_door(player, 'GT Double Switch Left to Exit Bypass', Lgcl), + create_door(player, 'GT Double Switch Left to Exit Bypass', Lgcl).no_exit(), # considered out of logic create_door(player, 'GT Double Switch Pot Corners to Entry Barrier - Orange', Lgcl), create_door(player, 'GT Double Switch Pot Corners to Exit Barrier - Blue', Lgcl), - create_door(player, 'GT Double Switch Pot Corners to Ranged Switches', Lgcl), - create_door(player, 'GT Double Switch Pot Corners Ranged Switches Exit', Lgcl), + create_door(player, 'GT Double Switch Pot Corners to Ranged Switches', Lgcl), # considered out of logic + create_door(player, 'GT Double Switch Pot Corners Ranged Switches Exit', Lgcl).no_exit(), # blocked here create_door(player, 'GT Double Switch Exit to Blue Barrier', Lgcl), create_door(player, 'GT Double Switch EN', Intr).dir(Ea, 0x9b, Top, High).small_key().pos(0), create_door(player, 'GT Spike Crystals WN', Intr).dir(We, 0x9b, Top, High).small_key().pos(0), @@ -1438,6 +1440,7 @@ def create_doors(world, player): world.get_door('GT Double Switch Entry to Pot Corners Barrier - Orange', player).barrier(CrystalBarrier.Orange) world.get_door('GT Double Switch Entry to Left Barrier - Orange', player).barrier(CrystalBarrier.Orange) world.get_door('GT Double Switch Entry Ranged Switches Exit', player).c_switch() + world.get_door('GT Double Switch Left Crystal Exit', player).c_switch() world.get_door('GT Double Switch Left to Entry Barrier - Orange', player).barrier(CrystalBarrier.Orange) world.get_door('GT Double Switch Left to Entry Bypass', player).barrier(CrystalBarrier.Blue) world.get_door('GT Double Switch Left to Pot Corners Bypass', player).barrier(CrystalBarrier.Blue) diff --git a/Dungeons.py b/Dungeons.py index 0acf7852..d5297400 100644 --- a/Dungeons.py +++ b/Dungeons.py @@ -304,7 +304,8 @@ gt_regions = [ 'GT Crystal Conveyor Corner - Ranged Crystal', 'GT Compass Room', 'GT Invisible Bridges', 'GT Invisible Catwalk', 'GT Conveyor Cross', 'GT Hookshot East Platform', 'GT Hookshot North Platform', 'GT Hookshot South Platform', 'GT Hookshot South Entry', 'GT Hookshot South Entry - Ranged Crystal', 'GT Map Room', - 'GT Double Switch Entry', 'GT Double Switch Pot Corners - Ranged Switches', 'GT Double Switch Pot Corners', 'GT Double Switch Left', + 'GT Double Switch Entry', 'GT Double Switch Pot Corners - Ranged Switches', 'GT Double Switch Pot Corners', + 'GT Double Switch Left', 'GT Double Switch Left - Crystal', 'GT Double Switch Entry - Ranged Switches', 'GT Double Switch Exit', 'GT Spike Crystal Left', 'GT Spike Crystal Right', 'GT Warp Maze - Left Section', 'GT Warp Maze - Mid Section', 'GT Warp Maze - Right Section', 'GT Warp Maze - Pit Section', 'GT Warp Maze - Pit Exit Warp Spot', diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 9c3b9502..7ece7e7b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -17,6 +17,7 @@ Thanks to qadan, cheuer, & compiling * 0.4.0.7 * Reduce flashing option added * Sprite author credit added + * Ranged Crystal switch rules tweaked * 0.4.0.6 * Hints now default to off * The maiden gives you a hint to the attic if you bring her to the unlit boss room diff --git a/Regions.py b/Regions.py index 9e6a324d..b2af454a 100644 --- a/Regions.py +++ b/Regions.py @@ -749,7 +749,8 @@ def create_dungeon_regions(world, player): create_dungeon_region(player, 'GT Double Switch Entry', 'Ganon\'s Tower', None, ['GT Double Switch NW', 'GT Double Switch Entry to Left Barrier - Orange', 'GT Double Switch Entry to Pot Corners Barrier - Orange', 'GT Double Switch Entry to Ranged Switches']), create_dungeon_region(player, 'GT Double Switch Entry - Ranged Switches', 'Ganon\'s Tower', None, ['GT Double Switch Entry Ranged Switches Exit']), - create_dungeon_region(player, 'GT Double Switch Left', 'Ganon\'s Tower', None, ['GT Double Switch Left to Entry Barrier - Orange', 'GT Double Switch Left to Entry Bypass', 'GT Double Switch Left to Pot Corners Bypass', 'GT Double Switch Left to Exit Bypass']), + create_dungeon_region(player, 'GT Double Switch Left', 'Ganon\'s Tower', None, ['GT Double Switch Left to Crystal', 'GT Double Switch Left to Entry Barrier - Orange', 'GT Double Switch Left to Entry Bypass', 'GT Double Switch Left to Pot Corners Bypass', 'GT Double Switch Left to Exit Bypass']), + create_dungeon_region(player, 'GT Double Switch Left - Crystal', 'Ganon\'s Tower', None, ['GT Double Switch Left Crystal Exit']), create_dungeon_region(player, 'GT Double Switch Pot Corners', 'Ganon\'s Tower', ['Ganons Tower - Double Switch Pot Key'], ['GT Double Switch Pot Corners to Entry Barrier - Orange', 'GT Double Switch Pot Corners to Exit Barrier - Blue', 'GT Double Switch Pot Corners to Ranged Switches']), create_dungeon_region(player, 'GT Double Switch Pot Corners - Ranged Switches', 'Ganon\'s Tower', None, ['GT Double Switch Pot Corners Ranged Switches Exit']), create_dungeon_region(player, 'GT Double Switch Exit', 'Ganon\'s Tower', None, ['GT Double Switch EN', 'GT Double Switch Exit to Blue Barrier']), @@ -870,7 +871,7 @@ def create_dungeon_regions(world, player): world.get_region('GT Crystal Conveyor Corner - Ranged Crystal', player).crystal_switch = True world.get_region('GT Hookshot South Platform', player).crystal_switch = True world.get_region('GT Hookshot South Entry - Ranged Crystal', player).crystal_switch = True - world.get_region('GT Double Switch Left', player).crystal_switch = True + world.get_region('GT Double Switch Left - Crystal', player).crystal_switch = True world.get_region('GT Double Switch Entry - Ranged Switches', player).crystal_switch = True world.get_region('GT Double Switch Pot Corners - Ranged Switches', player).crystal_switch = True world.get_region('GT Spike Crystal Left', player).crystal_switch = True diff --git a/Rules.py b/Rules.py index f1ade62a..3762b9bb 100644 --- a/Rules.py +++ b/Rules.py @@ -402,7 +402,7 @@ def global_rules(world, player): set_rule(world.get_entrance('Hera Front to Crystal', player), lambda state: state.can_hit_crystal(player)) set_rule(world.get_entrance('Hera Down Stairs Landing to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('Hera Down Stairs Landing', player), player))) # or state.has_beam_sword(player) set_rule(world.get_entrance('Hera Up Stairs Landing to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('Hera Up Stairs Landing', player), player))) # or state.has_beam_sword(player) - set_rule(world.get_entrance('Hera Back to Ranged Crystal', player), lambda state: False) # state.can_shoot_arrows(player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player) or state.has_beam_sword(player) or (state.has('Hookshot', player) and state.has('Red Boomerang', player)) + set_rule(world.get_entrance('Hera Back to Ranged Crystal', player), lambda state: state.can_shoot_arrows(player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player)) # or state.has_beam_sword(player) or (state.has('Hookshot', player) and state.has('Red Boomerang', player)) set_rule(world.get_entrance('Hera Front to Back Bypass', player), lambda state: state.can_use_bombs(player) or state.can_shoot_arrows(player) or state.has('Red Boomerang', player) or state.has('Blue Boomerang', player) or state.has('Cane of Somaria', player) or state.has('Fire Rod', player) or state.has('Ice Rod', player)) # or state.has_beam_sword(player) set_rule(world.get_entrance('Hera Basement Cage to Crystal', player), lambda state: state.can_hit_crystal(player)) set_rule(world.get_entrance('Hera Tridorm to Crystal', player), lambda state: state.can_hit_crystal(player)) @@ -430,7 +430,7 @@ def global_rules(world, player): set_rule(world.get_entrance('PoD Map Balcony to Ranged Crystal', player), lambda state: state.can_use_bombs(player) or state.has('Cane of Somaria', player)) # or state.has('Red Boomerang', player) set_rule(world.get_entrance('PoD Bow Statue Left to Crystal', player), lambda state: state.can_hit_crystal(player)) set_rule(world.get_entrance('PoD Bow Statue Right to Ranged Crystal', player), lambda state: state.has('Cane of Somaria', player)) - set_rule(world.get_entrance('PoD Bow Statue Left to Right Bypass', player), lambda state: state.has('Cane of Somaria', player)) # or state.can_use_bombs(player) or state.can_shoot_arrows(player) or state.has_beam_sword(player) or state.has('Red Boomrang', player) or state.has('Ice Rod', player) or state.has('Fire Rod', player) + set_rule(world.get_entrance('PoD Bow Statue Left to Right Bypass', player), lambda state: state.has('Cane of Somaria', player) or state.can_use_bombs(player) or state.can_shoot_arrows(player) or state.has('Red Boomerang', player) or state.has('Ice Rod', player) or state.has('Fire Rod', player)) # or state.has_beam_sword(player) set_rule(world.get_entrance('PoD Dark Pegs Landing to Ranged Crystal', player), lambda state: state.has('Cane of Somaria', player)) # or state.can_use_bombs(player) or state.has('Blue boomerang', player) or state.has('Red boomerang', player) set_rule(world.get_entrance('PoD Dark Pegs Middle to Ranged Crystal', player), lambda state: state.can_shoot_arrows(player) or state.can_use_bombs(player) or state.has('Red Boomerang', player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player) or (state.has('Hookshot', player) and state.can_reach_orange(world.get_region('PoD Dark Pegs Middle', player), player))) # or state.has_beam_sword(player) set_rule(world.get_entrance('PoD Dark Pegs Left to Ranged Crystal', player), lambda state: state.can_shoot_arrows(player) or state.has('Red Boomerang', player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player)) # or state.has_beam_sword(player) @@ -536,14 +536,15 @@ def global_rules(world, player): set_rule(world.get_entrance('GT Crystal Conveyor Left to Corner Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('GT Crystal Conveyor Left', player), player)) set_rule(world.get_entrance('GT Crystal Circles Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('GT Crystal Circles', player), player)) - set_rule(world.get_entrance('GT Hookshot Platform Barrier Bypass', player), lambda state: state.can_use_bombs(player) or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player) or state.has('Cane of Somaria', player)) # or state.has_Boots(player) /// There is a super precise trick where you can throw a pot and climp into the blue barrier, then sprint out of them. - set_rule(world.get_entrance('GT Hookshot South Entry to Ranged Crystal', player), lambda state: state.can_use_bombs(player) or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player) or state.has('Cane of Somaria', player)) + set_rule(world.get_entrance('GT Hookshot Platform Barrier Bypass', player), lambda state: state.can_use_bombs(player) or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player) or state.has('Cane of Somaria', player)) # or state.has_Boots(player) /// There is a super precise trick where you can throw a pot and climp into the blue barrier, then sprint out of them. + set_rule(world.get_entrance('GT Hookshot South Entry to Ranged Crystal', player), lambda state: state.can_use_bombs(player) or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player)) # or state.has('Cane of Somaria', player)) + set_rule(world.get_entrance('GT Double Switch Left to Crystal', player), lambda state: state.can_hit_crystal(player)) set_rule(world.get_entrance('GT Double Switch Entry to Ranged Switches', player), lambda state: False) # state.has('Cane of Somaria', player) set_rule(world.get_entrance('GT Double Switch Left to Entry Bypass', player), lambda state: True) # Can always use pots set_rule(world.get_entrance('GT Double Switch Left to Pot Corners Bypass', player), lambda state: state.can_use_bombs(player) or state.has('Cane of Somaria', player) or state.has('Red Boomerang', player)) # or (state.has('Blue Boomerang', player) and state.has('Hookshot', player)) or (state.has('Ice Rod', player) and state.has('Hookshot', player)) or state.has('Hookshot', player) /// You can do this with just a pot and a hookshot set_rule(world.get_entrance('GT Double Switch Left to Exit Bypass', player), lambda state: False) # state.can_use_bombs(player) or (state.has('Cane of Somaria', player) and (state.has('Red Boomerang', player) or (state.has('Hookshot', player) and state.has('Blue Boomerang', player)) or (state.has('Hookshot', player) and state.has('Ice Rod', player)))) set_rule(world.get_entrance('GT Double Switch Pot Corners to Ranged Switches', player), lambda state: False) # state.can_use_bombs(player) or state.has('Cane of Somaria', player) or (state.has('Cane of Somaria', player) and state.has_Boots(player)) /// There's two ways to interact with the switch. Somaria bounce at the top corner, or timed throws at the bottom corner. - set_rule(world.get_entrance('GT Spike Crystal Left to Right Bypass', player), lambda state: state.can_use_bombs(player) or state.has('Cane of Somaria', player) or state.has('Red Boomerang', player) or state.has('Blue Boomerang', player)) # or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.can_use_beam_sword(player) + set_rule(world.get_entrance('GT Spike Crystal Left to Right Bypass', player), lambda state: state.can_use_bombs(player) or state.has('Cane of Somaria', player) or state.has('Red Boomerang', player) or state.has('Blue Boomerang', player) or state.has('Fire Rod', player) or state.has('Ice Rod', player)) # or state.can_use_beam_sword(player) set_rule(world.get_entrance('GT Crystal Conveyor to Ranged Crystal', player), lambda state: state.can_use_bombs(player) or state.has('Cane of Somaria', player)) set_rule(world.get_entrance('GT Crystal Conveyor Corner to Ranged Crystal', player), lambda state: state.can_use_bombs(player) or state.has('Cane of Somaria', player)) set_rule(world.get_entrance('GT Crystal Conveyor Corner to Left Bypass', player), lambda state: state.can_use_bombs(player) or state.has('Cane of Somaria', player)) @@ -1210,6 +1211,9 @@ def standard_rules(world, player): 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Top of Pyramid']: add_rule(world.get_entrance(entrance, player), lambda state: state.has('Zelda Delivered', player)) + # don't allow bombs to get past here before zelda is rescued + set_rule(world.get_entrance('GT Hookshot South Entry to Ranged Crystal', player), lambda state: (state.can_use_bombs(player) and state.has('Zelda Delivered', player)) or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player)) # or state.has('Cane of Somaria', player)) + def find_rules_for_zelda_delivery(world, player): # path rules for backtracking