From 1a563a14fc155fd58d07c847d57bcd3209250a9a Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Mon, 6 May 2024 03:36:08 -0400 Subject: [PATCH] LTTP: Yet more LTTP logic fixes (#3270) --- worlds/alttp/Rules.py | 53 ++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index e13f0914..e0d812e6 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -64,20 +64,24 @@ def set_rules(world): if world.glitches_required[player] == 'no_glitches': no_glitches_rules(world, player) + forbid_bomb_jump_requirements(world, player) elif world.glitches_required[player] == 'overworld_glitches': # Initially setting no_glitches_rules to set the baseline rules for some # entrances. The overworld_glitches_rules set is primarily additive. no_glitches_rules(world, player) fake_flipper_rules(world, player) overworld_glitches_rules(world, player) + forbid_bomb_jump_requirements(world, player) elif world.glitches_required[player] in ['hybrid_major_glitches', 'no_logic']: no_glitches_rules(world, player) fake_flipper_rules(world, player) overworld_glitches_rules(world, player) underworld_glitches_rules(world, player) + bomb_jump_requirements(world, player) elif world.glitches_required[player] == 'minor_glitches': no_glitches_rules(world, player) fake_flipper_rules(world, player) + forbid_bomb_jump_requirements(world, player) else: raise NotImplementedError(f'Not implemented yet: Logic - {world.glitches_required[player]}') @@ -290,6 +294,9 @@ def global_rules(multiworld: MultiWorld, player: int): lambda state: state.has('Hookshot', player) or state.has('Pegasus Boots', player)) set_rule(multiworld.get_location('Hookshot Cave - Bottom Left', player), lambda state: state.has('Hookshot', player)) + set_rule(multiworld.get_location('Hyrule Castle - Map Guard Key Drop', player), + lambda state: can_kill_most_things(state, player, 1)) + set_rule(multiworld.get_entrance('Sewers Door', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 4) or ( multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal and multiworld.mode[ @@ -536,6 +543,8 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_location('Ganons Tower - Bob\'s Torch', player), lambda state: state.has('Pegasus Boots', player)) set_rule(multiworld.get_entrance('Ganons Tower (Tile Room)', player), lambda state: state.has('Cane of Somaria', player)) set_rule(multiworld.get_entrance('Ganons Tower (Hookshot Room)', player), lambda state: state.has('Hammer', player) and (state.has('Hookshot', player) or state.has('Pegasus Boots', player))) + if multiworld.pot_shuffle[player]: + set_rule(multiworld.get_location('Ganons Tower - Conveyor Cross Pot Key', player), lambda state: state.has('Hammer', player) and (state.has('Hookshot', player) or state.has('Pegasus Boots', player))) set_rule(multiworld.get_entrance('Ganons Tower (Map Room)', player), lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 8) or ( location_item_name(state, 'Ganons Tower - Map Chest', player) in [('Big Key (Ganons Tower)', player)] and state._lttp_has_key('Small Key (Ganons Tower)', player, 6))) @@ -900,7 +909,6 @@ def no_glitches_rules(world, player): add_rule(world.get_entrance('Ganons Tower (Double Switch Room)', 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 - forbid_bomb_jump_requirements(world, player) add_conditional_lamps(world, player) def fake_flipper_rules(world, player): @@ -928,12 +936,20 @@ def fake_flipper_rules(world, player): set_rule(world.get_entrance('East Dark World River Pier', player), lambda state: state.has('Moon Pearl', player)) -def forbid_bomb_jump_requirements(world, player): +def bomb_jump_requirements(multiworld, 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'] for location in DMs_room_chests: - add_rule(world.get_location(location, player), lambda state: state.has('Hookshot', player)) - set_rule(world.get_entrance('Paradox Cave Bomb Jump', player), lambda state: False) - set_rule(world.get_entrance('Skull Woods First Section Bomb Jump', player), lambda state: False) + add_rule(multiworld.get_location(location, player), lambda state: can_use_bombs(state, player), combine="or") + set_rule(multiworld.get_entrance('Paradox Cave Bomb Jump', player), lambda state: can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Skull Woods First Section Bomb Jump', player), lambda state: can_use_bombs(state, player)) + + +def forbid_bomb_jump_requirements(multiworld, 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'] + for location in DMs_room_chests: + add_rule(multiworld.get_location(location, player), lambda state: state.has('Hookshot', player)) + set_rule(multiworld.get_entrance('Paradox Cave Bomb Jump', player), lambda state: False) + set_rule(multiworld.get_entrance('Skull Woods First Section Bomb Jump', player), lambda state: False) DW_Entrances = ['Bumper Cave (Bottom)', @@ -1012,9 +1028,6 @@ def add_conditional_lamps(world, player): def open_rules(world, player): - set_rule(world.get_location('Hyrule Castle - Map Guard Key Drop', player), - lambda state: can_kill_most_things(state, player, 1)) - def basement_key_rule(state): if location_item_name(state, 'Sewers - Key Rat Key Drop', player) == ("Small Key (Hyrule Castle)", player): return state._lttp_has_key("Small Key (Hyrule Castle)", player, 2) @@ -1023,7 +1036,7 @@ def open_rules(world, player): set_rule(world.get_location('Hyrule Castle - Boomerang Guard Key Drop', player), lambda state: basement_key_rule(state) and can_kill_most_things(state, player, 2)) - set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), basement_key_rule) + set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), lambda state: basement_key_rule(state) and can_kill_most_things(state, player, 1)) set_rule(world.get_location('Sewers - Key Rat Key Drop', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 3) and can_kill_most_things(state, player, 1)) @@ -1031,8 +1044,10 @@ def open_rules(world, player): set_rule(world.get_location('Hyrule Castle - Big Key Drop', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 4) and can_kill_most_things(state, player, 1)) set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), - lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 4) and - state.has('Big Key (Hyrule Castle)', player)) + lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 4) + and state.has('Big Key (Hyrule Castle)', player) + and (world.enemy_health[player] in ("easy", "default") + or can_kill_most_things(state, player, 1))) def swordless_rules(world, player): @@ -1062,6 +1077,7 @@ def add_connection(parent_name, target_name, entrance_name, world, player): parent.exits.append(connection) connection.connect(target) + def standard_rules(world, player): add_connection('Menu', 'Hyrule Castle Secret Entrance', 'Uncle S&Q', world, player) world.get_entrance('Uncle S&Q', player).hide_path = True @@ -1073,18 +1089,23 @@ def standard_rules(world, player): if world.small_key_shuffle[player] != small_key_shuffle.option_universal: set_rule(world.get_location('Hyrule Castle - Boomerang Guard Key Drop', player), - lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 1)) + lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 1) + and can_kill_most_things(state, player, 2)) set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), - lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 1)) + lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 1) + and can_kill_most_things(state, player, 1)) set_rule(world.get_location('Hyrule Castle - Big Key Drop', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 2)) set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), - lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 2) and - state.has('Big Key (Hyrule Castle)', player)) + lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 2) + and state.has('Big Key (Hyrule Castle)', player) + and (world.enemy_health[player] in ("easy", "default") + or can_kill_most_things(state, player, 1))) set_rule(world.get_location('Sewers - Key Rat Key Drop', player), - lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 3)) + lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 3) + and can_kill_most_things(state, player, 1)) else: set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state.has('Big Key (Hyrule Castle)', player))