From 026bb642c67b0d3f31e7725ae0183dfbddd9d9b5 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Nov 2022 16:43:45 -0600 Subject: [PATCH 01/12] Added Old Man escorting to pathing logic --- BaseClasses.py | 13 ++++++++----- EntranceShuffle.py | 1 + ItemList.py | 6 ++++++ Items.py | 2 ++ OWEdges.py | 2 ++ OverworldShuffle.py | 1 + Regions.py | 9 ++++++--- Rules.py | 4 +++- 8 files changed, 29 insertions(+), 9 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index b773438f..df3a881f 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1543,10 +1543,13 @@ class Entrance(object): self.temp_path = [] def can_reach(self, state): - # Destination Pickup OW Only No Ledges Can S&Q Allow Mirror - multi_step_locations = { 'Pyramid Crack': ('Big Bomb', True, True, False, True), - 'Missing Smith': ('Frog', True, False, True, True), - 'Middle Aged Man': ('Dark Blacksmith Ruins', True, False, True, True) } + # Destination Pickup OW Only No Ledges Can S&Q Allow Mirror + multi_step_locations = { 'Pyramid Crack': ('Big Bomb', True, True, False, True), + 'Missing Smith': ('Frog', True, False, True, True), + 'Middle Aged Man': ('Dark Blacksmith Ruins', True, False, True, True), + 'Old Man Drop Off': ('Lost Old Man', True, False, False, True), + #'Revealing Light': ('Suspicious Maiden', False, False, False, False) } + } if self.name in multi_step_locations: if self not in state.path: @@ -2750,7 +2753,7 @@ class Spoiler(object): self.shops = [] self.bosses = OrderedDict() - self.suppress_spoiler_locations = ['Big Bomb', 'Dark Blacksmith Ruins', 'Frog', 'Middle Aged Man'] + self.suppress_spoiler_locations = ['Big Bomb', 'Dark Blacksmith Ruins', 'Frog', 'Middle Aged Man', 'Lost Old Man'] def set_overworld(self, entrance, exit, direction, player): if self.world.players == 1: diff --git a/EntranceShuffle.py b/EntranceShuffle.py index d2e493d6..ab106801 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -2317,6 +2317,7 @@ indirect_connections = { #'Blacksmith Area': 'Pyramid Fairy', # Hammerpegs #'Forgotten Forest Area': 'Pyramid Fairy', # Shield Shop #'Desert Area': 'Pyramid Fairy', # Mire Area + 'Old Man Drop Off': 'Old Man S&Q', 'Old Man Cave': 'Old Man S&Q' } # format: diff --git a/ItemList.py b/ItemList.py index 5115f7fa..b36e071b 100644 --- a/ItemList.py +++ b/ItemList.py @@ -216,6 +216,12 @@ def generate_itempool(world, player): world.push_item(world.get_location('Agahnim 2', player), ItemFactory('Beat Agahnim 2', player), False) world.get_location('Agahnim 2', player).event = True world.get_location('Agahnim 2', player).locked = True + world.push_item(world.get_location('Lost Old Man', player), ItemFactory('Escort Old Man', player), False) + world.get_location('Lost Old Man', player).event = True + world.get_location('Lost Old Man', player).locked = True + world.push_item(world.get_location('Old Man Drop Off', player), ItemFactory('Return Old Man', player), False) + world.get_location('Old Man Drop Off', player).event = True + world.get_location('Old Man Drop Off', player).locked = True world.push_item(world.get_location('Dark Blacksmith Ruins', player), ItemFactory('Pick Up Purple Chest', player), False) world.get_location('Dark Blacksmith Ruins', player).event = True world.get_location('Dark Blacksmith Ruins', player).locked = True diff --git a/Items.py b/Items.py index 59e6c228..e64b0bda 100644 --- a/Items.py +++ b/Items.py @@ -198,6 +198,8 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche 'Hidden Pits': (True, False, 'Event', 999, None, None, None, None, None, None, None, None), 'Zelda Herself': (True, False, 'Event', 999, None, None, None, None, None, None, None, None), 'Zelda Delivered': (True, False, 'Event', 999, None, None, None, None, None, None, None, None), + 'Escort Old Man': (True, False, 'Event', 999, None, None, None, None, None, None, None, None), + 'Return Old Man': (True, False, 'Event', 999, None, None, None, None, None, None, None, None), 'Farmable Bombs': (True, False, 'Event', 999, None, None, None, None, None, None, None, None), 'Farmable Rupees': (True, False, 'Event', 999, None, None, None, None, None, None, None, None), } diff --git a/OWEdges.py b/OWEdges.py index 0a7126b6..3f615aaa 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1024,6 +1024,7 @@ OWTileRegions = bidict({ 'West Death Mountain (Top)': 0x03, 'Spectacle Rock Ledge': 0x03, 'West Death Mountain (Bottom)': 0x03, + 'Old Man Drop Off': 0x03, 'East Death Mountain (Top West)': 0x05, 'East Death Mountain (Top East)': 0x05, @@ -1553,6 +1554,7 @@ OWExitTypes = { ], 'OWTerrain': ['Lost Woods Bush (West)', 'Lost Woods Bush (East)', + 'Old Man Drop Off', 'Spectacle Rock Approach', 'Spectacle Rock Leave', 'DM Hammer Bridge (West)', diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 9f8152e6..d5fc0cea 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1154,6 +1154,7 @@ mandatory_connections = [# Intra-tile OW Connections ('Lost Woods Bush (East)', 'Lost Woods West Area'), #pearl ('West Death Mountain Drop', 'West Death Mountain (Bottom)'), ('Spectacle Rock Drop', 'West Death Mountain (Top)'), + ('Old Man Drop Off', 'Old Man Drop Off'), ('DM Hammer Bridge (West)', 'East Death Mountain (Top East)'), #hammer ('DM Hammer Bridge (East)', 'East Death Mountain (Top West)'), #hammer ('East Death Mountain Spiral Ledge Drop', 'Spiral Cave Ledge'), diff --git a/Regions.py b/Regions.py index cb3eef6d..e4f0205e 100644 --- a/Regions.py +++ b/Regions.py @@ -15,7 +15,8 @@ def create_regions(world, player): create_lw_region(player, 'Lumberjack Area', None, ['Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Lumberjack House', 'Dark Lumberjack Mirror Spot', 'Lumberjack WN', 'Lumberjack SW']), create_lw_region(player, 'West Death Mountain (Top)', ['Ether Tablet'], ['Spectacle Rock Approach', 'West Death Mountain Drop', 'Tower of Hera', 'West Dark Death Mountain (Top) Mirror Spot', 'West Death Mountain EN']), create_lw_region(player, 'Spectacle Rock Ledge', ['Spectacle Rock'], ['Spectacle Rock Leave', 'Spectacle Rock Drop', 'Bubble Boy Mirror Spot']), - create_lw_region(player, 'West Death Mountain (Bottom)', 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)', 'West Dark Death Mountain (Bottom) Mirror Spot', 'West Death Mountain Teleporter', 'West Death Mountain ES']), + create_lw_region(player, 'West Death Mountain (Bottom)', ['Old Man'], ['Old Man Drop Off', '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)', 'West Dark Death Mountain (Bottom) Mirror Spot', 'West Death Mountain Teleporter', 'West Death Mountain ES']), + create_dw_region(player, 'Old Man Drop Off', ['Old Man Drop Off'], None), create_lw_region(player, 'East Death Mountain (Top West)', None, ['DM Hammer Bridge (West)', 'East Dark Death Mountain (Top West) Mirror Spot', 'East Death Mountain WN']), create_lw_region(player, 'East Death Mountain (Top East)', None, ['DM Hammer Bridge (East)', 'Floating Island Bridge (East)', 'East Death Mountain Spiral Ledge Drop', 'East Death Mountain Fairy Ledge Drop', 'East Death Mountain Mimic Ledge Drop', 'Paradox Cave (Top)', 'East Dark Death Mountain (Top East) Mirror Spot', 'East Death Mountain EN']), create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Ledge Drop', 'Spiral Mimic Bridge (West)', 'Spiral Cave', 'TR Ledge (West) Mirror Spot']), @@ -233,7 +234,7 @@ def create_regions(world, player): create_cave_region(player, 'Lumberjack Tree (top)', 'a drop\'s exit', ['Lumberjack Tree'], ['Lumberjack Tree (top to bottom)']), create_cave_region(player, 'Lumberjack Tree (bottom)', 'a drop\'s exit', None, ['Lumberjack Tree Exit']), create_cave_region(player, 'Lumberjack House', 'a boring house'), - create_cave_region(player, 'Old Man Cave', 'a connector', ['Old Man'], ['Old Man Cave Exit (East)']), + create_cave_region(player, 'Old Man Cave', 'a connector', ['Lost Old Man'], ['Old Man Cave Exit (East)']), create_cave_region(player, 'Old Man Cave Ledge', 'a connector', None, ['Old Man Cave Exit (West)', 'Old Man Cave Dropdown']), 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']), @@ -1200,7 +1201,7 @@ def adjust_locations(world, player): for l in ['Ganon', 'Agahnim 1', 'Agahnim 2', 'Dark Blacksmith Ruins', 'Middle Aged Man', 'Frog', 'Missing Smith', 'Floodgate', 'Trench 1 Switch', 'Trench 2 Switch', 'Swamp Drain', 'Attic Cracked Floor', 'Suspicious Maiden', 'Revealing Light', 'Big Bomb', 'Pyramid Crack', - 'Ice Block Drop', 'Zelda Pickup', 'Zelda Drop Off', 'Skull Star Tile']: + 'Ice Block Drop', 'Lost Old Man', 'Old Man Drop Off', 'Zelda Pickup', 'Zelda Drop Off', 'Skull Star Tile']: location = world.get_location_unsafe(l, player) if location: location.type = LocationType.Logical @@ -1585,6 +1586,8 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'), 'Ganon': (None, None, False, 'from me'), 'Agahnim 1': (None, None, False, 'from Ganon\'s wizardry form'), 'Agahnim 2': (None, None, False, 'from Ganon\'s wizardry form'), + 'Lost Old Man': (None, None, False, None), + 'Old Man Drop Off': (None, None, False, None), 'Floodgate': (None, None, False, None), 'Frog': (None, None, False, None), 'Missing Smith': (None, None, False, None), diff --git a/Rules.py b/Rules.py index a7941814..1edd64c6 100644 --- a/Rules.py +++ b/Rules.py @@ -180,7 +180,7 @@ def global_rules(world, player): #for exit in world.get_region('Flute Sky', player).exits: # exit.hide_path = True - set_rule(world.get_entrance('Old Man S&Q', player), lambda state: state.can_reach('Old Man', 'Location', player)) + set_rule(world.get_entrance('Old Man S&Q', player), lambda state: state.has('Return Old Man', player)) set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.can_flute(player)) set_rule(world.get_entrance('Flute Spot 2', player), lambda state: state.can_flute(player)) @@ -193,6 +193,8 @@ def global_rules(world, player): set_rule(world.get_location('Sunken Treasure', player), lambda state: state.has('Open Floodgate', player)) set_rule(world.get_location('Dark Blacksmith Ruins', player), lambda state: state.has('Return Smith', player)) + set_rule(world.get_location('Old Man', player), lambda state: state.has('Return Old Man', player)) + set_rule(world.get_location('Old Man Drop Off', player), lambda state: state.has('Escort Old Man', player)) set_rule(world.get_location('Middle Aged Man', player), lambda state: state.has('Pick Up Purple Chest', player)) # Can S&Q with chest set_rule(world.get_location('Purple Chest', player), lambda state: state.has('Deliver Purple Chest', player)) # Can S&Q with chest set_rule(world.get_location('Big Bomb', player), lambda state: state.has('Crystal 5', player) and state.has('Crystal 6', player)) From af6468961edd48af50aa57db1f2857b67f3e448f Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Nov 2022 16:55:26 -0600 Subject: [PATCH 02/12] Added Old Man escorting to pathing logic Removing mirror portal re-entry --- BaseClasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index df3a881f..2c510af3 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1547,7 +1547,7 @@ class Entrance(object): multi_step_locations = { 'Pyramid Crack': ('Big Bomb', True, True, False, True), 'Missing Smith': ('Frog', True, False, True, True), 'Middle Aged Man': ('Dark Blacksmith Ruins', True, False, True, True), - 'Old Man Drop Off': ('Lost Old Man', True, False, False, True), + 'Old Man Drop Off': ('Lost Old Man', True, False, False, False), #'Revealing Light': ('Suspicious Maiden', False, False, False, False) } } From 0a96b518ae41c507e752419cc772ac7d90f69a33 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Nov 2022 18:08:36 -0600 Subject: [PATCH 03/12] Consolidating Old Man pathing in spoiler log --- BaseClasses.py | 2 +- Regions.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 2c510af3..3a8d6604 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2753,7 +2753,7 @@ class Spoiler(object): self.shops = [] self.bosses = OrderedDict() - self.suppress_spoiler_locations = ['Big Bomb', 'Dark Blacksmith Ruins', 'Frog', 'Middle Aged Man', 'Lost Old Man'] + self.suppress_spoiler_locations = ['Big Bomb', 'Frog', 'Dark Blacksmith Ruins', 'Middle Aged Man', 'Lost Old Man', 'Old Man Drop Off'] def set_overworld(self, entrance, exit, direction, player): if self.world.players == 1: diff --git a/Regions.py b/Regions.py index e4f0205e..8f637e3a 100644 --- a/Regions.py +++ b/Regions.py @@ -15,8 +15,8 @@ def create_regions(world, player): create_lw_region(player, 'Lumberjack Area', None, ['Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Lumberjack House', 'Dark Lumberjack Mirror Spot', 'Lumberjack WN', 'Lumberjack SW']), create_lw_region(player, 'West Death Mountain (Top)', ['Ether Tablet'], ['Spectacle Rock Approach', 'West Death Mountain Drop', 'Tower of Hera', 'West Dark Death Mountain (Top) Mirror Spot', 'West Death Mountain EN']), create_lw_region(player, 'Spectacle Rock Ledge', ['Spectacle Rock'], ['Spectacle Rock Leave', 'Spectacle Rock Drop', 'Bubble Boy Mirror Spot']), - create_lw_region(player, 'West Death Mountain (Bottom)', ['Old Man'], ['Old Man Drop Off', '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)', 'West Dark Death Mountain (Bottom) Mirror Spot', 'West Death Mountain Teleporter', 'West Death Mountain ES']), - create_dw_region(player, 'Old Man Drop Off', ['Old Man Drop Off'], None), + create_lw_region(player, 'West Death Mountain (Bottom)', ['Old Man Drop Off'], ['Old Man Drop Off', '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)', 'West Dark Death Mountain (Bottom) Mirror Spot', 'West Death Mountain Teleporter', 'West Death Mountain ES']), + create_dw_region(player, 'Old Man Drop Off', ['Old Man'], None), create_lw_region(player, 'East Death Mountain (Top West)', None, ['DM Hammer Bridge (West)', 'East Dark Death Mountain (Top West) Mirror Spot', 'East Death Mountain WN']), create_lw_region(player, 'East Death Mountain (Top East)', None, ['DM Hammer Bridge (East)', 'Floating Island Bridge (East)', 'East Death Mountain Spiral Ledge Drop', 'East Death Mountain Fairy Ledge Drop', 'East Death Mountain Mimic Ledge Drop', 'Paradox Cave (Top)', 'East Dark Death Mountain (Top East) Mirror Spot', 'East Death Mountain EN']), create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Ledge Drop', 'Spiral Mimic Bridge (West)', 'Spiral Cave', 'TR Ledge (West) Mirror Spot']), From 8ae32fd76ea717f7b74745cc3eab5f417d08fc19 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Nov 2022 18:35:08 -0600 Subject: [PATCH 04/12] Add Old Man to bunny accessible locations --- Rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules.py b/Rules.py index 1edd64c6..5dc042a3 100644 --- a/Rules.py +++ b/Rules.py @@ -1807,7 +1807,7 @@ def set_bunny_rules(world, player, inverted): 'Hookshot Cave (Middle)', 'Pyramid', 'Spiral Cave (Top)', 'Fairy Ascension Cave (Drop)'] bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree', 'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', - 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', + 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', 'Old Man', 'Frog', 'Missing Smith', 'Dark Blacksmith Ruins', 'Purple Chest', 'Pyramid Crack', 'Big Bomb', 'Spectacle Rock', 'Bombos Tablet', 'Ether Tablet', 'Blacksmith', 'Master Sword Pedestal', 'Bottle Merchant', 'Sunken Treasure', 'Desert Ledge', From 590875b356bd4da6a293cedb85ffc7c3b0ef7e49 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Tue, 8 Nov 2022 18:53:07 -0600 Subject: [PATCH 05/12] Remove the sprite spawn delay when bonking prizes --- Rom.py | 2 +- asm/owrando.asm | 2 +- data/base2current.bps | Bin 104824 -> 104849 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Rom.py b/Rom.py index b229a7ac..8d3bf9ca 100644 --- a/Rom.py +++ b/Rom.py @@ -38,7 +38,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'ff9c003ee6c1277437a4480d583282fd' +RANDOMIZERBASEHASH = '3954c4e449c908a9e086a1fd5797c98b' class JsonRom(object): diff --git a/asm/owrando.asm b/asm/owrando.asm index a046b8da..363d9587 100644 --- a/asm/owrando.asm +++ b/asm/owrando.asm @@ -632,7 +632,7 @@ OWShuffle: ;offset is (8bytes * OW Slot ID) + (2bytes * direction) asl : rep #$20 : and.w #$00ff : pha : sep #$20 ;2 bytes per direction - lda $8a : tax : lda.l OWTileWorldAssoc,X : eor.l CurrentWorld : beq + + ldx $8a : lda.l OWTileWorldAssoc,X : eor.l CurrentWorld : beq + ; fake world, will treat this OW area as opposite world txa : eor.b #$40 : tax + txa : and #$40 : !add $700 : rep #$30 : and #$00ff : asl #3 diff --git a/data/base2current.bps b/data/base2current.bps index 66c714ea90eae5267ff6c92147cd0f6538ffb1f0..66b01ab4d15e33f5449b6c52fdf32ddb569cbd6d 100644 GIT binary patch delta 8666 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 delta 8462 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 X07<$pmw;YxLGDfWUp{R8``Z5jv+t`M From 5c8a5b3e4533e9debe752aff733435cd11fcff92 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 13 Nov 2022 16:03:39 -0600 Subject: [PATCH 06/12] Including GT entrance if Ganon is included in ER shuffle --- Rom.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index 8d3bf9ca..d6b81772 100644 --- a/Rom.py +++ b/Rom.py @@ -2204,7 +2204,10 @@ def write_strings(rom, world, player, team): if world.shuffle[player] not in ['simple', 'restricted', 'restricted_legacy']: entrances_to_hint.update(ConnectorEntrances) entrances_to_hint.update(DungeonEntrances) - if world.is_atgt_swapped(player): + if world.shuffle_ganon[player]: + entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) + entrances_to_hint.update({'Ganons Tower': 'The dark mountain tower'}) + elif world.is_atgt_swapped(player): entrances_to_hint.update({'Ganons Tower': 'The dark mountain tower'}) else: entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) From ff6bbbf1fc2ec9806444611d1f72facdff3c87ad Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 13 Nov 2022 16:17:18 -0600 Subject: [PATCH 07/12] Including Links House entrance if LH is included in ER shuffle --- Rom.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index d6b81772..33752226 100644 --- a/Rom.py +++ b/Rom.py @@ -2220,7 +2220,10 @@ def write_strings(rom, world, player, team): elif world.shopsanity[player]: entrances_to_hint.update(ShopEntrances) if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - if not world.is_bombshop_start(player): + if world.shufflelinks[player]: + entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) + entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) + elif not world.is_bombshop_start(player): entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) else: entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) From ab409baec1937f5201da6fa090322da489d19dff Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 13 Nov 2022 16:28:23 -0600 Subject: [PATCH 08/12] Fix incorrect references to world.shuffle_ganon --- EntranceShuffle.py | 20 ++++++++++---------- OverworldShuffle.py | 2 +- Rom.py | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index ab106801..c7586275 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -289,7 +289,7 @@ def link_entrances(world, player): else: caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3))) - if not world.shuffle_ganon: + if not world.shuffle_ganon[player]: connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: caves.append('Ganons Tower Exit') @@ -362,7 +362,7 @@ def link_entrances(world, player): else: lw_dungeons.append(tuple(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)'))) - if not world.shuffle_ganon: + if not world.shuffle_ganon[player]: connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: dw_dungeons.append('Ganons Tower Exit') @@ -448,7 +448,7 @@ def link_entrances(world, player): else: Dungeon_Exits.append(tuple(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)'))) - if not world.shuffle_ganon: + if not world.shuffle_ganon[player]: connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: Dungeon_Exits.append('Ganons Tower Exit') @@ -498,7 +498,7 @@ def link_entrances(world, player): else: caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3))) - if not world.shuffle_ganon: + if not world.shuffle_ganon[player]: connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: caves.append('Ganons Tower Exit') @@ -566,7 +566,7 @@ def link_entrances(world, player): caves.append('Hyrule Castle Secret Entrance Exit') caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) - if not world.shuffle_ganon: + if not world.shuffle_ganon[player]: connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', 'Ganons Tower Exit', player) connect_two_way(world, 'Pyramid Entrance' if not world.is_tile_swapped(0x1b, player) else 'Inverted Pyramid Entrance', 'Pyramid Exit', player) connect_entrance(world, 'Pyramid Hole' if not world.is_tile_swapped(0x1b, player) else 'Inverted Pyramid Hole', 'Pyramid', player) @@ -1036,7 +1036,7 @@ def scramble_holes(world, player): hole_entrances.append(('Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Drop')) hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance')) - if world.shuffle_ganon: + if world.shuffle_ganon[player]: hole_entrances.append(('Pyramid Entrance', 'Pyramid Hole') if not world.is_tile_swapped(0x1b, player) else ('Inverted Pyramid Entrance', 'Inverted Pyramid Hole')) hole_targets.append(('Pyramid Exit', 'Pyramid')) @@ -1078,7 +1078,7 @@ def scramble_holes(world, player): hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) # place pyramid hole - if not world.shuffle_ganon: + if not world.shuffle_ganon[player]: exit, target = ('Pyramid Exit', 'Pyramid') if not world.is_tile_swapped(0x1b, player): connect_two_way(world, 'Pyramid Entrance', exit, player) @@ -1112,7 +1112,7 @@ def simple_shuffle_dungeons(world, player): dungeon_exits = ['Eastern Palace Exit', 'Tower of Hera Exit', 'Agahnims Tower Exit', 'Thieves Town Exit', 'Skull Woods Final Section Exit', 'Palace of Darkness Exit', 'Ice Palace Exit', 'Misery Mire Exit', 'Swamp Palace Exit'] if not invFlag: - if not world.shuffle_ganon: + if not world.shuffle_ganon[player]: connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) else: dungeon_entrances.append('Ganons Tower') @@ -1121,7 +1121,7 @@ def simple_shuffle_dungeons(world, player): at_door = dungeon_exits.pop() else: dungeon_entrances.append('Ganons Tower') - if not world.shuffle_ganon: + if not world.shuffle_ganon[player]: at_door = 'Ganons Tower Exit' else: dungeon_exits.append('Ganons Tower Exit') @@ -1234,7 +1234,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player): # must connect front of hyrule castle to do escape connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) - if not world.shuffle_ganon: + if not world.shuffle_ganon[player]: connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: dungeon_exits.append('Ganons Tower Exit') diff --git a/OverworldShuffle.py b/OverworldShuffle.py index d5fc0cea..4a58676c 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -613,7 +613,7 @@ def shuffle_tiles(world, groups, result_list, do_grouped, player): parity[5] += 1 if 0x1b in group and world.mode[player] != 'standard': parity[5] += 1 - if 0x1b in group and world.shuffle_ganon: + if 0x1b in group and world.shuffle_ganon[player]: parity[5] -= 1 group_parity[group[0]] = parity diff --git a/Rom.py b/Rom.py index 33752226..39b977b6 100644 --- a/Rom.py +++ b/Rom.py @@ -2170,7 +2170,7 @@ def write_strings(rom, world, player, team): # First we take care of the one inconvenient dungeon in the appropriately simple shuffles. entrances_to_hint = {} entrances_to_hint.update(InconvenientDungeonEntrances) - if world.shuffle_ganon: + if world.shuffle_ganon[player]: if world.is_atgt_swapped(player): entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) else: @@ -2230,7 +2230,7 @@ def write_strings(rom, world, player, team): entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'}) if world.shuffle[player] in ['insanity', 'madness_legacy', 'insanity_legacy']: entrances_to_hint.update(InsanityEntrances) - if world.shuffle_ganon: + if world.shuffle_ganon[player]: if world.is_tile_swapped(0x1b, player): entrances_to_hint.update({'Inverted Pyramid Entrance': 'The extra castle passage'}) else: From d390047258225d6924f4f58d770332bb7655d066 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 13 Nov 2022 16:29:20 -0600 Subject: [PATCH 09/12] Removing most entrance hints for Lite/Lean ER --- Rom.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Rom.py b/Rom.py index 39b977b6..56656bf8 100644 --- a/Rom.py +++ b/Rom.py @@ -2183,8 +2183,9 @@ def write_strings(rom, world, player, team): entrances_to_hint = {} break # Now we write inconvenient locations for most shuffles and finish taking care of the less chaotic ones. - entrances_to_hint.update(InconvenientOtherEntrances) - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + if world.shuffle[player] not in ['lite', 'lean']: + entrances_to_hint.update(InconvenientOtherEntrances) + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'lite', 'lean']: hint_count = 0 elif world.shuffle[player] in ['simple', 'restricted', 'restricted_legacy']: hint_count = 2 @@ -2213,13 +2214,17 @@ def write_strings(rom, world, player, team): entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) elif world.shuffle[player] == 'restricted': entrances_to_hint.update(ConnectorEntrances) - entrances_to_hint.update(ItemEntrances) - if world.shuffle[player] not in ['lite', 'lean']: + if world.shuffle[player] in ['lite', 'lean']: + # all inconvenient dungeons + AT/GT stay in hint pool, but the remaining should exclude non-specific connector hints + for entrance in all_entrances: + if entrance.spot_type == 'Entrance' and entrance.connected_region \ + and entrance.connected_region.type != RegionType.Dungeon and entrance.name in list(ConnectorEntrances) + list(DungeonEntrances): + entrances_to_hint.pop(entrance.name) + else: + entrances_to_hint.update(ItemEntrances) entrances_to_hint.update(ShopEntrances) entrances_to_hint.update(OtherEntrances) - elif world.shopsanity[player]: - entrances_to_hint.update(ShopEntrances) - if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'lite', 'lean']: if world.shufflelinks[player]: entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) From e221046b966b635b0e94436e1447656941c6e7a8 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 18 Nov 2022 01:04:28 -0600 Subject: [PATCH 10/12] Corrected formatting in Changelog --- CHANGELOG.md | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfb1bf50..f5d3e076 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,13 +21,13 @@ - Various logic corrections, including the DR Bumper Cave fix for pottery logic ## 0.2.10.1 -- Merged DR v1.0.1.3 +- \~Merged v1.0.1.3~ - Fixed Zelda despawn in TT Prison - Fixed issue with key door usage in rainstate - Added missing modes to example mystery yaml ## 0.2.10.0 -- Merged DR v1.0.1.1-1.0.1.2 +- \~Merged v1.0.1.1-1.0.1.2~ - Removed text color from hint tiles - Removed Good Bee requirement from Mothula - Some keylogic/generation fixes @@ -56,7 +56,7 @@ - Fixed issue with pre-opened pyramid when not expected ### 0.2.8.0 -- ~Merged DR v1.0.1.0 - Pottery options, BPS support, MSU Resume, Collection Rate Counter~ +- \~Merged DR v1.0.1.0 - Pottery options, BPS support, MSU Resume, Collection Rate Counter~ - Various improvements to increase generation success rate and reduce generation time - Fixed issue with playthru recognizing Aga accessibility - Fixed issue with applying rules correctly to Murahdahla, fixing Murahdahla+Beatable issues @@ -81,7 +81,7 @@ - Added proper branch-specific versioning (ie. Dev branch has '-u' suffixing the version number while Release/Main branch does not) ### 0.2.7.0 -- ~Merged DR v1.0.0.3 - MANY changes, major things listed below~ +- \~Merged DR v1.0.0.3 - MANY changes, major things listed below~ - New Item Fills (Districts/Vanilla/Major Location/Dungeon) - New OW Map Prize Indicators (In ER, map checks can spoil dungeon locations with a user setting) - Forbidden Boss Items (Exclude certain dungeon items from dropping on bosses) @@ -132,7 +132,7 @@ - Fixed issue with incorrect Mirror bonking - Fixed issue with old man follower death to Pyramid - Fixed Hera boss music not playing when boss not defeated -- ~Merged DR v0.5.1.7 - TT boss trap door fix/Applied Glitched flag~ +- \~Merged DR v0.5.1.7 - TT boss trap door fix/Applied Glitched flag~ ### 0.2.4.0 - Added Guaranteed OWR Reachability @@ -158,7 +158,7 @@ - Fake flipper damage fix improved to skip the long delay after the scroll - Fixed missing Blue Potion in Lake Shop in Inverted - Added legacy OW Crossed option 'None (Allowed)' to support old behavior when invalid option was used in Mystery -- ~Merged DR v0.5.1.6 - Money balancing fix/Boss logic fixes with Bombbag~ +- \~Merged DR v0.5.1.6 - Money balancing fix/Boss logic fixes with Bombbag~ ### 0.2.3.3 - Added OW Layout validation that reduces the cases where some screens are unreachable @@ -200,7 +200,7 @@ - Fixed music track change to Sanc music when Standard mode is delivering Zelda - Fixed SP flooding issue - Fixed issue with Shuffle Ganon in CLI/GUI -- ~Merged DR v0.5.1.5 - Mystery subweights~ +- \~Merged DR v0.5.1.5 - Mystery subweights~ ### 0.2.1.2 - Fixed issue with whirlpools not changing world when in Crossed OW @@ -221,7 +221,7 @@ - Smith deletion on S+Q only occurs if Blacksmith not reachable from starting locations - Spoiler log improvements to prevent spoiling in the beginning 'meta' section - Various minor fixes and improvements -- ~Merged DR v0.5.1.4 - ROM bug fixes/keylogic improvements~ +- \~Merged DR v0.5.1.4 - ROM bug fixes/keylogic improvements~ ### 0.1.9.4 - Hotfix for bad 0.1.9.3 version @@ -234,11 +234,11 @@ ### 0.1.9.2 - Fixed spoiler log and mystery for new Crossed/Mixed structure - Minor preparations and tweaks to ER framework (added global Entrance/Exit pool) -- ~Merged DR v0.5.1.2 - Blind Prison shuffled outside TT/Keylogic Improvements~ +- \~Merged DR v0.5.1.2 - Blind Prison shuffled outside TT/Keylogic Improvements~ ### 0.1.9.1 - Fixed logic issue with leaving IP entrance not requiring flippers -- ~Merged DR v0.5.1.1 - Map Indicator Fix/Boss Shuffle Bias/Shop Hints~ +- \~Merged DR v0.5.1.1 - Map Indicator Fix/Boss Shuffle Bias/Shop Hints~ ### 0.1.9.0 - Expanded Crossed OW to four separate options, see Readme for details @@ -252,7 +252,7 @@ - Fixed issues with Link/Bunny state in Crossed OW - Fixed issue with Standard+Parallel not using vanilla connections for Escape - Fixed issue with Mystery for OW boolean options -- ~Merged DR v0.5.1.0 - Major Keylogic Update~ +- \~Merged DR v0.5.1.0 - Major Keylogic Update~ ### 0.1.8.1 - Fixed issue with activating flute in DW (OW Mixed) @@ -267,12 +267,12 @@ - Added OW Shuffle support for Plando module (needs user testing) - Fixed issue with Sanc start at TR as bunny when it is LW - Fixed issue with Pyramid Hole not getting shuffled -- ~Merged DR v0.5.0.3 - Minor DR fixes~ +- \~Merged DR v0.5.0.3 - Minor DR fixes~ ### 0.1.7.4 - Fixed issue with Mixed OW failing to generate when HC/Pyramid is swapped - Various fixes to improve generation rates for Mixed OW Shuffle -- ~Merged DR v0.5.0.2 - Shuffle SFX~ +- \~Merged DR v0.5.0.2 - Shuffle SFX~ ### 0.1.7.3 - Fixed minor issue with ambient SFX stopping and starting on OW screen load @@ -292,10 +292,10 @@ ### 0.1.7.0 - Expanded new DR bomb logic to all modes (bomb usage in logic only if there is an unlimited supply of bombs available) -- ~Merged DR v0.5.0.1 - Bombbag mode / Enemizer fixes~ +- \~Merged DR v0.5.0.1 - Bombbag mode / Enemizer fixes~ ### 0.1.6.9 -- ~Merged DR v0.4.0.12 - Secure random update / Credits fix~ +- \~Merged DR v0.4.0.12 - Secure random update / Credits fix~ ### 0.1.6.8 - Implemented a smarter Balanced Flute Shuffle algorithm @@ -309,14 +309,14 @@ - Fixed Boss Music when boss room is entered thru straight stairs - Suppressed in-dungeon music changes when DR is enabled - Fixed issue with Pyramid Exit exiting to wrong location in ER -- ~Merged DR v0.4.0.11 - Various DR changes~ +- \~Merged DR v0.4.0.11 - Various DR changes~ ### 0.1.6.6 -- ~Merged DR v0.4.0.9 - P/C Indicator / Credits fix / CLI Hints Fix~ +- \~Merged DR v0.4.0.9 - P/C Indicator / Credits fix / CLI Hints Fix~ ### 0.1.6.5 - Reduced chance of diagonal flute spot in Balanced -- ~Merged DR v0.4.0.8 - Boss Indicator / Psuedo Boots / Quickswap Update / Credits Updates~ +- \~Merged DR v0.4.0.8 - Boss Indicator / Psuedo Boots / Quickswap Update / Credits Updates~ ### 0.1.6.4 - Fixed Frogsmith and Stumpy and restored progression in these locations @@ -355,15 +355,15 @@ ### 0.1.5.0 - Added OW Tile Swap setting - Fixed horizontal VRAM visual loading glitch on megatiles -- ~~Merged DR v0.4.0.7 - Fast Credits / Reduced Flashing / Sprite Author in Credits~~ Didn't fully merge +- ~\~Merged DR v0.4.0.7 - Fast Credits / Reduced Flashing / Sprite Author in Credits~~ Didn't fully merge ### 0.1.4.3 -- ~Merged DR v0.4.0.6 - TT Maiden Attic Hint / DR Entrance Floor Mat Mods / Hard/Expert Item Pool Fix~ +- \~Merged DR v0.4.0.6 - TT Maiden Attic Hint / DR Entrance Floor Mat Mods / Hard/Expert Item Pool Fix~ ### 0.1.4.2 - Modified various OW map terrain specific to OW Shuffle - Changed World check to table-based vs OW ID-based (should have no effect with current modes) -- ~Merged DR v0.4.0.5 - Mystery Boss Shuffle Fix / Swordless+Hard Item Pool Fix / Insanity+Inverted ER Fixes~ +- \~Merged DR v0.4.0.5 - Mystery Boss Shuffle Fix / Swordless+Hard Item Pool Fix / Insanity+Inverted ER Fixes~ ### 0.1.4.1 - Moved Inverted Pyramid Entrance to top of HC Ledge @@ -377,11 +377,11 @@ - Various logic fixes and region prep for Inverted - Fixed muted MSU-1 music in door rando when descending GT Climb stairs - Fixed Standard + Vanilla (thanks compiling) -- ~Merged DR v0.4.0.4 - Shuffle Link's House / Experimental Bunny Start / 10 Bomb Fix~ +- \~Merged DR v0.4.0.4 - Shuffle Link's House / Experimental Bunny Start / 10 Bomb Fix~ ### 0.1.3.0 - Added OWG Logic for OW Shuffle -- ~Merged DR v0.4.0.2 - OWG Framework / YAML~ +- \~Merged DR v0.4.0.2 - OWG Framework / YAML~ ### 0.1.2.2 - Re-purposed OW Shuffle setting to Layout Shuffle @@ -390,7 +390,7 @@ ### 0.1.2.1 - Made possible fix for Standard -- ~Merged DR v0.3.1.10 - Fixed Standard generation~ +- \~Merged DR v0.3.1.10 - Fixed Standard generation~ ### 0.1.2.0 - Added 'Parallel Worlds' toggle option @@ -400,7 +400,7 @@ ### 0.1.1.2 - If Link's current position fits within the incoming gap, Link will not get re-centered to the incoming gap - Added Rule for Pearl required to drop down back of SW -- ~Merged DR v0.3.1.8 - Improved Shopsanity pricing - Fixed Retro generation~ +- \~Merged DR v0.3.1.8 - Improved Shopsanity pricing - Fixed Retro generation~ ### 0.1.1.1 - Fixed camera unlocking issue From 7e7b29ac27a2cb4295f51f406bfda30b2f729f64 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 19 Nov 2022 16:55:48 -0600 Subject: [PATCH 11/12] Fixed copy_world_premature error in multiworld --- Main.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Main.py b/Main.py index a5708194..3ea1afb4 100644 --- a/Main.py +++ b/Main.py @@ -694,9 +694,8 @@ def copy_world_premature(world, player): copied_entrance.door = copied_door if copied_door: copied_door.entrance = copied_entrance - for player, portals in world.dungeon_portals.items(): - for portal in portals: - connect_portal(portal, ret, player) + for portal in world.dungeon_portals[player]: + connect_portal(portal, ret, player) set_rules(ret, player) From c886f529ee0280592a3a6ff66a65c090673b2ede Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 19 Nov 2022 17:03:24 -0600 Subject: [PATCH 12/12] Version bump 0.2.11.3 --- CHANGELOG.md | 7 +++++++ OverworldShuffle.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5d3e076..7e03485c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.2.11.3 +- Fixed error during multiworld generation +- Added proper Old Man pathing to the logic and spoiler playthru +- Removed the delay in spawning sprites when bonking items out of bonk locations +- Removed useless hints in Lite/Lean ER that are already categorically assumed +- Added GT and Links House entrance hints when either are shuffled in the pool + ## 0.2.11.2 - Implemented proper Districting with Mixed OWR, affecting Hints and District modes - Suppressed item locations in spoiler log that are junk or logical diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 4a58676c..127a1280 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -7,7 +7,7 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType from OverworldGlitchRules import create_owg_connections from Utils import bidict -version_number = '0.2.11.2' +version_number = '0.2.11.3' # branch indicator is intentionally different across branches version_branch = '-u'