From b8f81ade67fde409a08dd741b51766517e4a720f Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:44:00 +1000 Subject: [PATCH 1/3] Remove Spectacle Rock Cave ledges from inverted bomb shop locations, not normal bomb shop locations. Update inverted bomb shop tests --- EntranceShuffle.py | 4 ++-- test/inverted/TestInvertedBombRules.py | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index d7d733c001..2ae3235e0e 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -2290,6 +2290,8 @@ Bomb_Shop_Multi_Cave_Doors = ['Hyrule Castle Entrance (South)', 'Death Mountain Return Cave (East)', 'Death Mountain Return Cave (West)', 'Spectacle Rock Cave Peak', + 'Spectacle Rock Cave', + 'Spectacle Rock Cave (Bottom)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', @@ -2630,8 +2632,6 @@ Inverted_Bomb_Shop_Multi_Cave_Doors = ['Hyrule Castle Entrance (South)', 'Death Mountain Return Cave (East)', 'Death Mountain Return Cave (West)', 'Spectacle Rock Cave Peak', - 'Spectacle Rock Cave', - 'Spectacle Rock Cave (Bottom)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', diff --git a/test/inverted/TestInvertedBombRules.py b/test/inverted/TestInvertedBombRules.py index c28879959d..4914d2e370 100644 --- a/test/inverted/TestInvertedBombRules.py +++ b/test/inverted/TestInvertedBombRules.py @@ -3,7 +3,7 @@ import unittest from BaseClasses import World from Dungeons import create_dungeons from EntranceShuffle import connect_entrance, Inverted_LW_Entrances, Inverted_LW_Dungeon_Entrances, Inverted_LW_Single_Cave_Doors, Inverted_Old_Man_Entrances, Inverted_DW_Entrances, Inverted_DW_Dungeon_Entrances, Inverted_DW_Single_Cave_Doors, \ - Inverted_LW_Entrances_Must_Exit, Inverted_LW_Dungeon_Entrances_Must_Exit + Inverted_LW_Entrances_Must_Exit, Inverted_LW_Dungeon_Entrances_Must_Exit, Inverted_Bomb_Shop_Multi_Cave_Doors, Inverted_Bomb_Shop_Single_Cave_Doors, Inverted_Blacksmith_Single_Cave_Doors, Inverted_Blacksmith_Multi_Cave_Doors from InvertedRegions import create_inverted_regions from ItemList import difficulties from Rules import set_inverted_big_bomb_rules @@ -31,6 +31,12 @@ class TestInvertedBombRules(unittest.TestCase): entrance.connected_region.entrances.remove(entrance) entrance.connected_region = None + def testInvalidEntrancesAreNotUsed(self): + entrances = list(Inverted_Blacksmith_Multi_Cave_Doors + Inverted_Blacksmith_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors + Inverted_Bomb_Shop_Single_Cave_Doors) + invalid_entrances = ['Desert Palace Entrance (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)', 'Pyramid Fairy'] + for invalid_entrance in invalid_entrances: + self.assertNotIn(invalid_entrance, entrances) + def testInvalidEntrances(self): for entrance_name in ['Desert Palace Entrance (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']: entrance = self.world.get_entrance(entrance_name, 1) From 7199c375d79aaff528fa00964d271044efa67aaf Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:28:01 +1000 Subject: [PATCH 2/3] Fix inverted TR tests - ER requires access to Witches Hut for potions. --- test/inverted/TestInvertedTurtleRock.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/inverted/TestInvertedTurtleRock.py b/test/inverted/TestInvertedTurtleRock.py index c61acbd3f6..7975abebfc 100644 --- a/test/inverted/TestInvertedTurtleRock.py +++ b/test/inverted/TestInvertedTurtleRock.py @@ -200,7 +200,8 @@ class TestInvertedTurtleRock(TestInverted): ["Turtle Rock - Boss", False, [], ['Magic Mirror', 'Lamp']], ["Turtle Rock - Boss", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']], ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], - ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Moon Pearl', 'Beat Agahnim 1', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Magic Upgrade (1/2)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)','Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Moon Pearl', 'Hookshot', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']] ]) \ No newline at end of file From 11a91b96c636ca5820fff11cfc8dddb6b4bc8f67 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:22:50 +1000 Subject: [PATCH 3/3] Set inverted blacksmith to require light world access using the mirror or a portal (via starting in Link's House / Old Man Cave doesn't work). Set the flag allowing the blacksmith to visit Link's House in simple inverted shuffle. --- EntranceShuffle.py | 10 +++++----- Rom.py | 2 +- Rules.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 2ae3235e0e..565bef65ea 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1253,7 +1253,7 @@ def link_inverted_entrances(world, player): caves = list(Cave_Exits + Cave_Three_Exits + Old_Man_House) single_doors = list(Single_Cave_Doors) bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors) - blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors) + blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) door_targets = list(Inverted_Single_Cave_Targets) # place links house @@ -1335,7 +1335,7 @@ def link_inverted_entrances(world, player): old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Inverted Agahnims Tower', 'Tower of Hera']) caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits) # don't need to consider three exit caves, have one exit caves to avoid parity issues bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors) - blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors) + blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) door_targets = list(Inverted_Single_Cave_Targets) old_man_house = list(Old_Man_House) @@ -1486,7 +1486,7 @@ def link_inverted_entrances(world, player): old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Inverted Agahnims Tower', 'Tower of Hera']) caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits + Old_Man_House) # don't need to consider three exit caves, have one exit caves to avoid parity issues bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors) - blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors) + blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) door_targets = list(Inverted_Single_Cave_Targets) # randomize which desert ledge door is a must-exit @@ -1610,7 +1610,7 @@ def link_inverted_entrances(world, player): # bomb shop logic for. # Specifically we could potentially add: 'Dark Death Mountain Ledge (East)' and doors associated with pits bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors + ['Turtle Rock Isolated Ledge Entrance', 'Hookshot Cave Back Entrance']) - blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors) + blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors) door_targets = list(Inverted_Single_Cave_Targets) random.shuffle(doors) @@ -2646,7 +2646,7 @@ Inverted_Bomb_Shop_Multi_Cave_Doors = ['Hyrule Castle Entrance (South)', 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'] -Inverted_Blacksmith_Multi_Cave_Doors = [] # same as non-inverted +Inverted_Blacksmith_Multi_Cave_Doors = Blacksmith_Multi_Cave_Doors # same as non-inverted Inverted_LW_Single_Cave_Doors = LW_Single_Cave_Doors + ['Inverted Big Bomb Shop'] diff --git a/Rom.py b/Rom.py index e41f0f4a8c..e51359c938 100644 --- a/Rom.py +++ b/Rom.py @@ -1018,7 +1018,7 @@ def patch_rom(world, player, rom): rom.write_bytes(0x02F539, [0xEA, 0xEA, 0xEA, 0xEA, 0xEA] if world.powder_patch_required[player] else [0xAD, 0xBF, 0x0A, 0xF0, 0x4F]) # allow smith into multi-entrance caves in appropriate shuffles - if world.shuffle in ['restricted', 'full', 'crossed', 'insanity']: + if world.shuffle in ['restricted', 'full', 'crossed', 'insanity'] or (world.shuffle == 'simple' and world.mode == 'inverted'): rom.write_byte(0x18004C, 0x01) # set correct flag for hera basement item diff --git a/Rules.py b/Rules.py index 0ae6ff61e8..52650a51e6 100644 --- a/Rules.py +++ b/Rules.py @@ -521,7 +521,7 @@ def inverted_rules(world, player): set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player)) set_rule(world.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player)) # can be fake flippered into, but is in weird state inside that might prevent you from doing things. Can be improved in future Todo - set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player) or (state.can_reach('Light World', 'Region', player) and state.has_Mirror(player))) + set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player) and (state.has_Pearl(player) or state.has('Beat Agahnim 1', player)) or (state.can_reach('Light World', 'Region', player) and state.has_Mirror(player))) # Need LW access using Mirror or Portal set_rule(world.get_location('Missing Smith', player), lambda state: state.has('Get Frog', player) and state.can_reach('Blacksmiths Hut', 'Region', player)) # Can't S&Q with smith set_rule(world.get_location('Blacksmith', player), lambda state: state.has('Return Smith', player)) set_rule(world.get_location('Magic Bat', player), lambda state: state.has('Magic Powder', player) and state.has_Pearl(player))