From 2541e6d7a03373999154fb92a920e73d7c4ca918 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Tue, 4 Jan 2022 20:38:11 -0600 Subject: [PATCH 01/73] Fixed issue with CLI vs GUI for TFH args --- BaseClasses.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index 40472347..752b96ae 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2839,7 +2839,9 @@ class Spoiler(object): if self.world.custom and p in self.world.customitemarray: self.metadata['triforcegoal'][p], self.metadata['triforcepool'][p] = set_default_triforce(self.metadata['goal'][p], self.world.customitemarray[p]["triforcepiecesgoal"], self.world.customitemarray[p]["triforcepieces"]) else: - self.metadata['triforcegoal'][p], self.metadata['triforcepool'][p] = set_default_triforce(self.metadata['goal'][p], self.world.treasure_hunt_count, self.world.treasure_hunt_total) + custom_goal = self.world.treasure_hunt_count[p] if isinstance(self.world.treasure_hunt_count, dict) else self.world.treasure_hunt_count + custom_total = self.world.treasure_hunt_total[p] if isinstance(self.world.treasure_hunt_total, dict) else self.world.treasure_hunt_total + self.metadata['triforcegoal'][p], self.metadata['triforcepool'][p] = set_default_triforce(self.metadata['goal'][p], custom_goal, custom_total) def parse_data(self): self.medallions = OrderedDict() From 45bb92151f262f9f51b39b241e9db05d885985c8 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 4 Jan 2022 22:10:42 -0700 Subject: [PATCH 02/73] -Fix for Inverted Mode: Dark Lake Hylia shop sells a blue potion -Fix for Ijwu's enemizer: Boss door in Thieves' Town no longer closes after the maiden hint -AllowAccidentalMajorGlitches set for no logic --- Main.py | 2 +- RELEASENOTES.md | 4 ++++ Regions.py | 1 + Rom.py | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Main.py b/Main.py index 05363732..2648b6e8 100644 --- a/Main.py +++ b/Main.py @@ -29,7 +29,7 @@ from Fill import sell_potions, sell_keys, balance_multiworld_progression, balanc from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops from Utils import output_path, parse_player_names -__version__ = '0.5.1.6-u' +__version__ = '0.5.1.7-u' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index eaa45e2b..4590df80 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -15,6 +15,10 @@ CLI: ```--bombbag``` # Bug Fixes and Notes. +* 0.5.1.7 + * Fix for Inverted Mode: Dark Lake Hylia shop defaults to selling a blue potion + * Fix for Ijwu's enemizer: Boss door in Thieves' Town no longer closes after the maiden hint if Blind is shuffled to Theives' Town in boss shuffle + crossed mode + * No logic now sets the AllowAccidentalMajorGlitches flag in the rom appropriately * 0.5.1.6 * Rules fixes for TT (Boss and Cell) can now have TT Big Key if not otherwise required (boss shuffle + crossed dungeon) * BUg fix for money balancing diff --git a/Regions.py b/Regions.py index 546cd49b..8ea63502 100644 --- a/Regions.py +++ b/Regions.py @@ -957,6 +957,7 @@ def create_shops(world, player): if world.mode[player] == 'inverted' and region_name == 'Dark Lake Hylia Shop': locked = True inventory = [('Blue Potion', 160), ('Blue Shield', 50), ('Bombs (10)', 50)] + custom = True region = world.get_region(region_name, player) shop = Shop(region, room_id, type, shopkeeper, custom, locked, sram) region.shop = shop diff --git a/Rom.py b/Rom.py index ad4ce2d4..2cf54d6a 100644 --- a/Rom.py +++ b/Rom.py @@ -333,6 +333,7 @@ def patch_enemizer(world, player, rom, local_rom, enemizercli, random_sprite_on_ rom.write_bytes(0xEA081, [0x5c, 0x00, 0x80, 0xb7, 0xc9, 0x6, 0xf0, 0x24, 0xad, 0x3, 0x4, 0x29, 0x20, 0xf0, 0x1d]) rom.write_byte(0x200101, 0) # Do not close boss room door on entry. + rom.write_byte(0x1B0101, 0) # Do not close boss room door on entry. (for Ijwu's enemizer) if random_sprite_on_hit: _populate_sprite_table() @@ -1462,6 +1463,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x1800A3, 0x01) # enable correct world setting behaviour after agahnim kills rom.write_byte(0x1800A4, 0x01 if world.logic[player] != 'nologic' else 0x00) # enable POD EG fix rom.write_byte(0x180042, 0x01 if world.save_and_quit_from_boss else 0x00) # Allow Save and Quit after boss kill + rom.write_byte(0x180358, 0x01 if world.logic[player] == 'nologic' else 0x00) # remove shield from uncle rom.write_bytes(0x6D253, [0x00, 0x00, 0xf6, 0xff, 0x00, 0x0E]) From f5641c063a7a936ce2f55b02766c59e4a3f622aa Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 5 Jan 2022 02:26:50 -0600 Subject: [PATCH 03/73] Implemented OWR reachability guarantee --- OverworldShuffle.py | 163 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 152 insertions(+), 11 deletions(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 0dd9223a..3e68f9b6 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -948,17 +948,148 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F return explored_regions def validate_layout(world, player): - sectors = [[r for l in s for r in l] for s in world.owsectors[player]] - for sector in sectors: - entrances_present = False - for region_name in sector: - region = world.get_region(region_name, player) - if any(x.spot_type == 'Entrance' for x in region.exits): - entrances_present = True - break - if not entrances_present and not all(r in isolated_regions for r in sector): - return False + if world.accessibility[player] == 'beatable': + return True + + entrance_connectors = { + 'East Death Mountain (Bottom)': ['East Death Mountain (Top East)'], + 'Kakariko Suburb Area': ['Maze Race Ledge'], + 'Maze Race Ledge': ['Kakariko Suburb Area'], + 'Desert Area': ['Desert Ledge', 'Desert Palace Mouth'], + 'East Dark Death Mountain (Top)': ['Dark Death Mountain Floating Island'], + 'East Dark Death Mountain (Bottom)': ['East Dark Death Mountain (Top)'], + 'Turtle Rock Area': ['Dark Death Mountain Ledge', + 'Dark Death Mountain Isolated Ledge'], + 'Dark Death Mountain Ledge': ['Turtle Rock Area'], + 'Dark Death Mountain Isolated Ledge': ['Turtle Rock Area'] + } + sane_connectors = { + # guaranteed dungeon access + 'Skull Woods Forest': ['Skull Woods Forest (West)'], + 'Skull Woods Forest (West)': ['Skull Woods Forest'], + # guaranteed dropdown access + 'Graveyard Area': ['Sanctuary Area'], + 'Pyramid Area': ['Pyramid Exit Ledge'] + } + if not world.is_tile_swapped(0x0a, player): + if not world.is_tile_swapped(0x03, player): + entrance_connectors['Mountain Entry Entrance'] = ['West Death Mountain (Bottom)'] + entrance_connectors['Mountain Entry Ledge'] = ['West Death Mountain (Bottom)'] + entrance_connectors['West Death Mountain (Bottom)'] = ['Mountain Entry Ledge'] + else: + entrance_connectors['Mountain Entry Entrance'] = ['West Dark Death Mountain (Bottom)'] + entrance_connectors['Bumper Cave Entrance'] = ['Bumper Cave Ledge'] + else: + if not world.is_tile_swapped(0x03, player): + entrance_connectors['Bumper Cave Entrance'] = ['West Death Mountain (Bottom)'] + entrance_connectors['Bumper Cave Ledge'] = ['West Death Mountain (Bottom)'] + entrance_connectors['West Death Mountain (Bottom)'] = ['Bumper Cave Ledge'] + else: + entrance_connectors['Bumper Cave Entrance'] = ['West Dark Death Mountain (Bottom)'] + entrance_connectors['Mountain Entry Entrance'] = ['Mountain Entry Ledge'] + + from Main import copy_world + from Utils import stack_size3a + from EntranceShuffle import default_dungeon_connections, default_connector_connections, default_item_connections, default_shop_connections, default_drop_connections, default_dropexit_connections + + dungeon_entrances = list(zip(*default_dungeon_connections + [('Ganons Tower', '')]))[0] + connector_entrances = list(zip(*default_connector_connections))[0] + item_entrances = list(zip(*default_item_connections))[0] + shop_entrances = list(zip(*default_shop_connections))[0] + drop_entrances = list(zip(*default_drop_connections + default_dropexit_connections))[0] + + def explore_region(region_name, region=None): + if stack_size3a() > 500: + raise GenerationException(f'Infinite loop detected for "{region_name}" located at \'validate_layout\'') + + explored_regions.append(region_name) + if not region: + region = base_world.get_region(region_name, player) + for exit in region.exits: + if exit.connected_region is not None and exit.connected_region.name not in explored_regions \ + and exit.connected_region.type in [RegionType.LightWorld, RegionType.DarkWorld]: + explore_region(exit.connected_region.name, exit.connected_region) + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple'] \ + and region_name in entrance_connectors: + for dest_region in entrance_connectors[region_name]: + if dest_region not in explored_regions: + explore_region(dest_region) + if world.shuffle[player] not in ['insanity'] and region_name in sane_connectors: + for dest_region in sane_connectors[region_name]: + if dest_region not in explored_regions: + explore_region(dest_region) + + for p in range(1, world.players + 1): + world.key_logic[p] = {} + base_world = copy_world(world) + world.key_logic = {} + explored_regions = list() + + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not world.shufflelinks[player]: + if not world.is_tile_swapped(0x2c, player): + start_region = 'Links House Area' + else: + start_region = 'Bomb Shop Area' + explore_region(start_region) + + if not world.is_tile_swapped(0x30, player): + start_region = 'Desert Palace Teleporter Ledge' + else: + start_region = 'Misery Mire Teleporter Ledge' + explore_region(start_region) + + if not world.is_tile_swapped(0x1b, player): + start_region = 'Pyramid Area' + else: + start_region = 'Hyrule Castle Ledge' + explore_region(start_region) + + unreachable_regions = {} + unreachable_count = -1 + while unreachable_count != len(unreachable_regions): + # find unreachable regions + unreachable_regions = {} + flat_sectors = [[r for l in s for r in l] for s in world.owsectors[player]] + for sector in flat_sectors: + for region_name in sector: + if region_name not in explored_regions and region_name not in isolated_regions: + region = base_world.get_region(region_name, player) + unreachable_regions[region_name] = region + + # loop thru unreachable regions to check if some can be excluded + unreachable_count = len(unreachable_regions) + for region_name in reversed(unreachable_regions): + # check if can be accessed flute + if unreachable_regions[region_name].type == RegionType.LightWorld: + owid = OWTileRegions[region_name] + if owid < 0x80 and any(f[1] == owid and region_name in f[0] for f in flute_data.values()): + if world.owFluteShuffle[player] != 'vanilla' or owid % 0x40 in [0x03, 0x16, 0x18, 0x2c, 0x2f, 0x3b, 0x3f]: + unreachable_regions.pop(region_name) + explore_region(region_name) + break + # check if entrances in region could be used to access region + if world.shuffle[player] != 'vanilla': + for entrance in [e for e in unreachable_regions[region_name].exits if e.spot_type == 'Entrance']: + if (entrance.name == 'Links House' and (world.mode == 'inverted' or not world.shufflelinks[player] or world.shuffle[player] in ['dungeonssimple', 'dungeonsfull', 'lite', 'lean'])) \ + or (entrance.name == 'Big Bomb Shop' and (world.mode != 'inverted' or not world.shufflelinks[player] or world.shuffle[player] in ['dungeonssimple', 'dungeonsfull', 'lite', 'lean'])) \ + or (entrance.name == 'Ganons Tower' and (world.mode != 'inverted' and not world.shuffle_ganon[player])) \ + or (entrance.name in ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] and world.shuffle[player] not in ['insanity']) \ + or entrance.name == 'Tavern North': + continue # these are fixed entrances and cannot be used for gaining access to region + if entrance.name not in drop_entrances \ + and ((entrance.name in dungeon_entrances and world.shuffle[player] not in ['dungeonssimple', 'simple', 'restricted']) \ + or (entrance.name in connector_entrances and world.shuffle[player] not in ['dungeonssimple', 'dungeonsfull', 'simple']) \ + or (entrance.name in item_entrances + ([] if world.shopsanity[player] else shop_entrances) and world.shuffle[player] not in ['dungeonssimple', 'dungeonsfull', 'lite', 'lean'])): + unreachable_regions.pop(region_name) + explore_region(region_name) + break + if unreachable_count != len(unreachable_regions): + break + + if len(unreachable_regions): + return False + return True test_connections = [ @@ -1719,7 +1850,17 @@ default_connections = [#('Lost Woods NW', 'Master Sword Meadow SC'), isolated_regions = [ 'Death Mountain Floating Island', - 'Mimic Cave Ledge' + 'Mimic Cave Ledge', + 'Mountain Entry Ledge', + 'Maze Race Prize', + 'Maze Race Ledge', + 'Desert Ledge', + 'Desert Palace Entrance (North) Spot', + 'Desert Palace Mouth', + 'Dark Death Mountain Floating Island', + 'Dark Death Mountain Ledge', + 'Dark Death Mountain Isolated Ledge', + 'Bumper Cave Ledge' ] flute_data = { From a1fc3d4701df3d2294d6357fe41e18af771a1825 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 5 Jan 2022 02:53:19 -0600 Subject: [PATCH 04/73] Fixed issue with incorrect parity calculation for Whirlpool Shuffle --- OverworldShuffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 3e68f9b6..c8510775 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -502,7 +502,7 @@ def shuffle_tiles(world, groups, result_list, player): exist_dw_regions.extend(dw_regions) # check whirlpool parity - valid_whirlpool_parity = world.owCrossed[player] not in ['none', 'grouped'] or len(OrderedDict.fromkeys(new_results[0] + [0x0f, 0x12, 0x15, 0x33, 0x35, 0x3f, 0x55, 0x7f])) % 2 == 0 + valid_whirlpool_parity = world.owCrossed[player] not in ['none', 'grouped'] or len([o for o in new_results[0] if o in [0x0f, 0x12, 0x15, 0x33, 0x35, 0x3f, 0x55, 0x7f]]) % 2 == 0 (exist_owids, exist_lw_regions, exist_dw_regions) = result_list exist_owids.extend(new_results[0]) From e3d35c1d29f556dbfffd5b95177b00fd3f78aa4a Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 5 Jan 2022 02:54:17 -0600 Subject: [PATCH 05/73] Version bump 0.2.4.0 --- CHANGELOG.md | 6 ++++++ OverworldShuffle.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bb81edf..4f4e4a34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +### 0.2.4.0 +- Added Guaranteed OWR Reachability +- Fixed incorrect parity calc for Whirlpool Shuffle +- Fixed error with generating seeds with GUI +- CLI fixes for triforce piece arguments + ### 0.2.3.6 - Added Trinity goal (8/10 default TF pieces) - Many improvements to TFH pool allocation diff --git a/OverworldShuffle.py b/OverworldShuffle.py index c8510775..c3997a13 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -5,7 +5,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl from Regions import mark_dark_world_regions, mark_light_world_regions from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel -__version__ = '0.2.3.6-u' +__version__ = '0.2.4.0-u' def link_overworld(world, player): # setup mandatory connections From 6163f7e85757cd05aa4d49f44bfdbd09c70dae72 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 5 Jan 2022 03:00:16 -0600 Subject: [PATCH 06/73] Implemented OWR reachability guarantee --- OverworldShuffle.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index c3997a13..5ef65c4c 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1033,6 +1033,10 @@ def validate_layout(world, player): start_region = 'Bomb Shop Area' explore_region(start_region) + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'lite', 'lean'] and world.mode == 'inverted': + start_region = 'Dark Chapel Area' + explore_region(start_region) + if not world.is_tile_swapped(0x30, player): start_region = 'Desert Palace Teleporter Ledge' else: From e15b1dad57bc454fc90a6b665ec5ab7e1461a432 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 5 Jan 2022 03:27:44 -0600 Subject: [PATCH 07/73] Implemented OWR reachability guarantee --- OverworldShuffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 5ef65c4c..041ed087 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1030,7 +1030,7 @@ def validate_layout(world, player): if not world.is_tile_swapped(0x2c, player): start_region = 'Links House Area' else: - start_region = 'Bomb Shop Area' + start_region = 'Big Bomb Shop Area' explore_region(start_region) if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'lite', 'lean'] and world.mode == 'inverted': From 4f3ff95f81e4f0a65fcc478b9b29370c58538832 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 5 Jan 2022 14:37:10 -0700 Subject: [PATCH 08/73] -Baserom update -Incorporate some rom PRs -Updated Houlihan to exit to wherever Link's House is (inverted, too) --- EntranceShuffle.py | 11 ++++++++++- RELEASENOTES.md | 3 +++ Rom.py | 2 +- asm/drhooks.asm | 9 ++++++--- asm/gfx.asm | 10 ++++++++++ data/base2current.bps | Bin 136173 -> 81941 bytes 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 390cf83d..b8715b06 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -109,6 +109,7 @@ def link_entrances(world, player): links_house_doors = [i for i in LW_Single_Cave_Doors if i not in Isolated_LH_Doors_Open] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house if links_house in bomb_shop_doors: bomb_shop_doors.remove(links_house) if links_house in blacksmith_doors: @@ -173,6 +174,7 @@ def link_entrances(world, player): links_house_doors = [i for i in lw_entrances if i not in Isolated_LH_Doors_Open] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house if links_house in lw_entrances: lw_entrances.remove(links_house) @@ -337,6 +339,7 @@ def link_entrances(world, player): links_house_doors = [i for i in lw_entrances + lw_must_exits if i not in Isolated_LH_Doors_Open] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house if links_house in lw_entrances: lw_entrances.remove(links_house) if links_house in lw_must_exits: @@ -467,6 +470,7 @@ def link_entrances(world, player): links_house_doors = [i for i in links_house_doors if i not in exclusions] links_house = random.choice(list(links_house_doors)) connect_two_way(world, links_house, 'Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house if links_house in entrances: entrances.remove(links_house) elif links_house in must_exits: @@ -937,6 +941,7 @@ def link_entrances(world, player): links_house_doors = [i for i in links_house_doors if i not in exclusions] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house exit_pool.remove(links_house) doors.remove(links_house) @@ -1301,6 +1306,7 @@ def link_inverted_entrances(world, player): links_house_doors = [i for i in DW_Single_Cave_Doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Inverted Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house if links_house in bomb_shop_doors: bomb_shop_doors.remove(links_house) if links_house in blacksmith_doors: @@ -1381,6 +1387,7 @@ def link_inverted_entrances(world, player): links_house_doors = [i for i in dw_entrances if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Inverted Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house if links_house in dw_entrances: dw_entrances.remove(links_house) @@ -1510,6 +1517,7 @@ def link_inverted_entrances(world, player): links_house_doors = [i for i in dw_entrances if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Inverted Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house if links_house in dw_entrances: dw_entrances.remove(links_house) @@ -1647,6 +1655,7 @@ def link_inverted_entrances(world, player): links_house_doors = [i for i in entrances + must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Inverted Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house if links_house in entrances: entrances.remove(links_house) elif links_house in must_exits: @@ -1780,6 +1789,7 @@ def link_inverted_entrances(world, player): links_house_doors = [i for i in doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Inverted Links House Exit', player) + connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) # should match link's house doors.remove(links_house) exit_pool.remove(links_house) @@ -3329,7 +3339,6 @@ inverted_mandatory_connections = [('Links House S&Q', 'Inverted Links House'), ('EDDM Flute', 'The Sky'), ('Dark Grassy Lawn Flute', 'The Sky'), ('Hammer Peg Area Flute', 'The Sky'), - ('Chris Houlihan Room Exit', 'Pyramid Ledge'), ('Bush Covered Lawn Inner Bushes', 'Light World'), ('Bush Covered Lawn Outer Bushes', 'Bush Covered Lawn'), ('Bush Covered Lawn Mirror Spot', 'Dark Grassy Lawn'), diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 4590df80..50cf5282 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -16,9 +16,12 @@ CLI: ```--bombbag``` # Bug Fixes and Notes. * 0.5.1.7 + * Baserom update * Fix for Inverted Mode: Dark Lake Hylia shop defaults to selling a blue potion * Fix for Ijwu's enemizer: Boss door in Thieves' Town no longer closes after the maiden hint if Blind is shuffled to Theives' Town in boss shuffle + crossed mode * No logic now sets the AllowAccidentalMajorGlitches flag in the rom appropriately + * Houlihan room now exits wherever Link's House is shuffled to + * Rom fixes from Catobat and Codemann8. Thanks! * 0.5.1.6 * Rules fixes for TT (Boss and Cell) can now have TT Big Key if not otherwise required (boss shuffle + crossed dungeon) * BUg fix for money balancing diff --git a/Rom.py b/Rom.py index 2cf54d6a..72eaa421 100644 --- a/Rom.py +++ b/Rom.py @@ -32,7 +32,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '7511c811385f87c6ae0909e7bbe379cb' +RANDOMIZERBASEHASH = '5112ddd931bda3d9979097bc39a5e768' class JsonRom(object): diff --git a/asm/drhooks.asm b/asm/drhooks.asm index 1d3b485b..a5815d98 100644 --- a/asm/drhooks.asm +++ b/asm/drhooks.asm @@ -76,6 +76,9 @@ nop : jsl OverridePaletteHeader org $02817e ; Bank02.asm : 414 (LDA $02811E, X) jsl FixAnimatedTiles +org $0aef43 ; UnderworldMap_RecoverGFX +jsl FixCloseDungeonMap + org $028a06 ; Bank02.asm : 1941 Dungeon_ResetTorchBackgroundAndPlayer JSL FixWallmasterLamp @@ -186,9 +189,9 @@ Main_ShowTextMessage: ; Conditionally disable UW music changes in Door Rando org $028ADB ; <- Bank02.asm:2088-2095 (LDX.b #$14 : LDA $A0 ...) -JSL.l Underworld_DoorDown_Entry : CPX #$10 -db $B0, $21 ; BCS $028B04 -BRA + : NOP #6 : + +JSL.l Underworld_DoorDown_Entry : CPX #$FF +BEQ + : db $80, $1C ; BRA $028B04 +NOP #6 : + org $02C3F2 ; <- Bank02.asm:10521 Unused call Underworld_DoorDown_Call: diff --git a/asm/gfx.asm b/asm/gfx.asm index b22fba62..94cb8848 100644 --- a/asm/gfx.asm +++ b/asm/gfx.asm @@ -45,6 +45,16 @@ FixAnimatedTiles: + LDA $02802E, X ; what we wrote over RTL +FixCloseDungeonMap: + LDA.l DRMode : CMP #$02 : BNE .vanilla + LDA $040C : BMI .vanilla + LSR : TAX + LDA.l DungeonTilesets,x + RTL + .vanilla + LDA $7EC20E + RTL + FixWallmasterLamp: ORA $0458 STY $1C : STA $1D : RTL ; what we wrote over diff --git a/data/base2current.bps b/data/base2current.bps index 12fb7ccd3056db6ef6002726b78a903d201b0ea0..195cdbabe2fa4fcd9810871d63e9c41014f9bd44 100644 GIT binary patch delta 17200 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 W2qA1=Fq{i9QBY+Qe(9*%9sVCIX14DD delta 71525 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 XP%`17>81upd!4wZ+_xvYKI#7fyX3cx From 81702c4eca6d02fd5b506f4e34ac4c13461057cc Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 6 Jan 2022 11:41:38 -0600 Subject: [PATCH 09/73] Some Inverted terrain changes for EDM --- Rom.py | 2 +- data/base2current.bps | Bin 87028 -> 87371 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index a4a64dc9..5bcd4e15 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'a85465d4ceb66703e60dd2eef42a9a0d' +RANDOMIZERBASEHASH = '26009bf2175c79e9a02ae406230d6a50' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 6e708352e6458f776cba7168531c98b333ef6bda..3c2b1b1322ac5c8f7ed1889ca51dd6f4814403bd 100644 GIT binary patch delta 4104 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 G!~X!uf;mS3 delta 3657 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 H=DzqZHu!Dk From b27fed99f79bfa9216315547eda3db4d3e8fdd4e Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 6 Jan 2022 11:42:00 -0600 Subject: [PATCH 10/73] Some Inverted terrain changes for EDM --- Rom.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Rom.py b/Rom.py index 5bcd4e15..7684251c 100644 --- a/Rom.py +++ b/Rom.py @@ -2533,6 +2533,8 @@ def set_inverted_mode(world, player, rom, inverted_buffer): rom.write_bytes(snes_to_pc(0x1BD1DD), [0xA4, 0x06, 0x82, 0x9E, 0x06, 0x82, 0xFF, 0xFF]) # add warps under rocks rom.write_byte(0x180089, 0x01) # open TR after exit rom.write_bytes(0x0086E, [0x5C, 0x00, 0xA0, 0xA1]) # TR tail + rom.write_bytes(snes_to_pc(0x04E7A3), [0x20, 0x06]) # Top peg moved down, for peg puzzle + rom.write_byte(snes_to_pc(0x04E7E4), 0x10) # Remove TR portal overlay if world.shuffle[player] in ['vanilla']: world.fix_trock_doors[player] = True if world.is_tile_swapped(0x10, player): From c1e60c33c94783bbb1e5fbb4868c39e880393ff6 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 6 Jan 2022 12:45:58 -0600 Subject: [PATCH 11/73] Some Inverted terrain changes for EDM --- Rom.py | 2 +- data/base2current.bps | Bin 87371 -> 87371 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index 7684251c..a6af7a2c 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '26009bf2175c79e9a02ae406230d6a50' +RANDOMIZERBASEHASH = '828431c06c6c17d4e30d821cfadb70fa' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 3c2b1b1322ac5c8f7ed1889ca51dd6f4814403bd..d52ac3cc59e1e786f2a12cb9857daf089524ad36 100644 GIT binary patch delta 208 zcmWm3F-rn*7{K9P&1f}B^nIFJO=Ko-aYMW75+!8<}%=_w=i z3!$%!)o+D~GSKZ#)$fE@Nt9fv)MrAf6zU5hQ%d!-8eOAj^o@ZrGRDTln3|v0h>hgH xNR7kx8$F-MM*s1rJCo0s>nxB5ia;5t0(GDXw85vsKp84y^&?@V zBJ%g6ZH!rQ*xzJTJ Date: Thu, 6 Jan 2022 18:41:11 -0600 Subject: [PATCH 12/73] Reversed Old Man spawn on OW in Inverted --- Rom.py | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/Rom.py b/Rom.py index a6af7a2c..55a9346e 100644 --- a/Rom.py +++ b/Rom.py @@ -2501,30 +2501,7 @@ def set_inverted_mode(world, player, rom, inverted_buffer): write_int16(rom, 0x15AEE + 2*0x38, 0x00E0) write_int16(rom, 0x15AEE + 2*0x25, 0x000C) - if world.is_tile_swapped(0x03, player): - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] \ - or (world.shuffle[player] == 'simple' and world.is_tile_swapped(0x05, player)): - rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) # mountain cave starts on OW - write_int16(rom, snes_to_pc(0x02D8DE), 0x00F1) # change mountain cave spawn point to just outside old man cave - rom.write_bytes(snes_to_pc(0x02D910), [0x1F, 0x1E, 0x1F, 0x1F, 0x03, 0x02, 0x03, 0x03]) - write_int16(rom, snes_to_pc(0x02D924), 0x0300) - write_int16(rom, snes_to_pc(0x02D932), 0x1F10) - write_int16(rom, snes_to_pc(0x02D940), 0x1FC0) - write_int16(rom, snes_to_pc(0x02D94E), 0x0378) - write_int16(rom, snes_to_pc(0x02D95C), 0x0187) - write_int16(rom, snes_to_pc(0x02D96A), 0x017F) - rom.write_byte(snes_to_pc(0x02D972), 0x06) - rom.write_byte(snes_to_pc(0x02D979), 0x00) - rom.write_byte(snes_to_pc(0x02D980), 0xFF) - rom.write_byte(snes_to_pc(0x02D987), 0x00) - rom.write_byte(snes_to_pc(0x02D98E), 0x22) - rom.write_byte(snes_to_pc(0x02D995), 0x12) - write_int16(rom, snes_to_pc(0x02D9A2), 0x0000) - write_int16(rom, snes_to_pc(0x02D9B0), 0x0007) - rom.write_byte(snes_to_pc(0x02D9B8), 0x12) - - rom.write_bytes(0x180247, [0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00]) # indicates the overworld door being used for the single entrance spawn point if world.is_tile_swapped(0x05, player): rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) # add warp under rock rom.write_byte(snes_to_pc(0x1BC428), 0x00) # remove secret portal From 44eb10a9dba0b95d6c2f8d81ace2d7e731ac3542 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 6 Jan 2022 18:48:47 -0600 Subject: [PATCH 13/73] Reversed Old Man spawn on OW in Inverted --- EntranceShuffle.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 5e6c772f..9d01196f 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -47,11 +47,6 @@ def link_entrances(world, player): dropexit_connections.append(tuple(('Inverted Pyramid Entrance', 'Pyramid Exit'))) connect_simple(world, 'Other World S&Q', 'Hyrule Castle Ledge', player) - if not world.is_tile_swapped(0x03, player): - connect_simple(world, 'Old Man S&Q', 'Old Man House', player) - else: - connect_simple(world, 'Old Man S&Q', 'West Dark Death Mountain (Bottom)', player) - unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits) Cave_Exits.extend(Cave_Exits_Directional) @@ -2078,6 +2073,7 @@ Exit_Pool_Base = ['Links House Exit', # these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions mandatory_connections = [('Links House S&Q', 'Links House'), + ('Old Man S&Q', 'Old Man House'), # UW Connections ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), From d01ddabcafdbfae907c71b0d2589195c1e41332f Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 12 Jan 2022 02:53:38 -0600 Subject: [PATCH 14/73] Fixed issue with duplicate regions in OW sectors --- OverworldShuffle.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 041ed087..20715557 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -869,7 +869,7 @@ def build_sectors(world, player): if (any(r in unique_regions for r in explored_regions)): for s in range(len(sectors)): if (any(r in sectors[s] for r in explored_regions)): - sectors[s] = list(list(sectors[s]) + list(explored_regions)) + sectors[s] = list(dict.fromkeys(list(sectors[s]) + list(explored_regions))) break else: sectors.append(explored_regions) @@ -895,7 +895,7 @@ def build_sectors(world, player): if (any(r in unique_regions for r in explored_regions)): for s2 in range(len(sectors2)): if (any(r in sectors2[s2] for r in explored_regions)): - sectors2[s2] = list(sectors2[s2] + explored_regions) + sectors2[s2] = list(dict.fromkeys(sectors2[s2] + explored_regions)) break else: sectors2.append(explored_regions) From 8ade8e79b514adf6627050d8b11648fbfe0bf453 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 12 Jan 2022 02:54:24 -0600 Subject: [PATCH 15/73] Fixed issue with OW layout validation error with reversible lists --- OverworldShuffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 20715557..ff663e13 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1049,7 +1049,7 @@ def validate_layout(world, player): start_region = 'Hyrule Castle Ledge' explore_region(start_region) - unreachable_regions = {} + unreachable_regions = OrderedDict() unreachable_count = -1 while unreachable_count != len(unreachable_regions): # find unreachable regions From 5a9f1098835a55d5269fc2c4894090891a9dcb6d Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 12 Jan 2022 03:14:24 -0600 Subject: [PATCH 16/73] Reversed Old Man Cave entrance placement in Inverted --- EntranceShuffle.py | 87 ++++++++++------------------------------------ OWEdges.py | 2 +- 2 files changed, 20 insertions(+), 69 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 9d01196f..8f92644d 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -81,20 +81,6 @@ def link_entrances(world, player): for entrancename, exitname in inverted_default_connections: connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit')) - # inverted entrance mods - ignore_pool = True - for owid in swapped_connections.keys(): - if world.is_tile_swapped(owid, player): - for (entrancename, exitname) in swapped_connections[owid]: - try: - connect_two_way(world, entrancename, exitname, player) - except RuntimeError: - connect_entrance(world, entrancename, exitname, player) - - if world.is_tile_swapped(0x03, player) and not world.is_tile_swapped(0x0a, player): - connect_entrance(world, 'Death Mountain Return Cave (West)', 'Dark Death Mountain Healer Fairy', player) - elif world.is_tile_swapped(0x0a, player) and not world.is_tile_swapped(0x03, player): - connect_two_way(world, 'Bumper Cave (Top)', 'Death Mountain Return Cave Exit (West)', player) ignore_pool = False # dungeon entrance shuffle @@ -124,7 +110,8 @@ def link_entrances(world, player): scramble_holes(world, player) # list modification - lw_wdm_entrances = ['Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', + lw_wdm_entrances = ['Old Man Cave (West)', 'Death Mountain Return Cave (West)', + '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)'] lw_edm_entrances = ['Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Spiral Cave', @@ -134,13 +121,9 @@ def link_entrances(world, player): caves = list(Cave_Exits) three_exit_caves = list(Cave_Three_Exits) - Two_Door_Caves_Directional = list() + Two_Door_Caves_Directional = [('Bumper Cave (Bottom)', 'Bumper Cave (Top)')] Two_Door_Caves = [('Elder House (East)', 'Elder House (West)'), ('Superbunny Cave (Bottom)', 'Superbunny Cave (Top)')] - if not world.is_tile_swapped(0x0a, player): - Two_Door_Caves_Directional.append(tuple({'Bumper Cave (Bottom)', 'Bumper Cave (Top)'})) - else: - Two_Door_Caves_Directional.append(tuple({'Old Man Cave (West)', 'Death Mountain Return Cave (West)'})) if not world.is_tile_swapped(0x05, player): Two_Door_Caves_Directional.append(tuple({'Hookshot Cave', 'Hookshot Cave Back Entrance'})) else: @@ -174,43 +157,25 @@ def link_entrances(world, player): caves.extend(list(Old_Man_House)) caves.extend(list(three_exit_caves)) - if (not world.is_tile_swapped(0x18, player)) or (not world.is_tile_swapped(0x03, player)): # ability to activate flute in LW - candidates = [e for e in lw_wdm_entrances if e != 'Old Man House (Bottom)'] + candidates = [e for e in lw_wdm_entrances if e != 'Old Man House (Bottom)'] + random.shuffle(candidates) + old_man_exit = candidates.pop() + lw_wdm_entrances.remove(old_man_exit) + connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player) + + if 0x03 in world.owswaps[player][0] == 0x05 in world.owswaps[player][0]: # if WDM and EDM are in same world + candidates = lw_wdm_entrances + lw_edm_entrances random.shuffle(candidates) - old_man_exit = candidates.pop() - lw_wdm_entrances.remove(old_man_exit) - connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player) - - if not world.is_tile_swapped(0x0a, player): - lw_wdm_entrances.extend(['Old Man Cave (West)', 'Death Mountain Return Cave (West)']) - else: - lw_wdm_entrances.extend(['Bumper Cave (Bottom)', 'Bumper Cave (Top)']) - - if 0x03 in world.owswaps[player][0] == 0x05 in world.owswaps[player][0]: # if WDM and EDM are in same world - candidates = lw_wdm_entrances + lw_edm_entrances - random.shuffle(candidates) - old_man_entrance = candidates.pop() + old_man_entrance = candidates.pop() + if old_man_entrance in lw_wdm_entrances: lw_wdm_entrances.remove(old_man_entrance) - if old_man_entrance in lw_wdm_entrances: - lw_wdm_entrances.remove(old_man_entrance) - elif old_man_entrance in lw_edm_entrances: - lw_edm_entrances.remove(old_man_entrance) - else: - random.shuffle(lw_wdm_entrances) - old_man_entrance = lw_wdm_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + elif old_man_entrance in lw_edm_entrances: + lw_edm_entrances.remove(old_man_entrance) else: - # force connection to DM - random.shuffle(ddm_entrances) - old_man_exit = ddm_entrances.pop() - connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player) - - # place old man, bumper cave bottom to DDM entrances not in east bottom - if not world.is_tile_swapped(0x0a, player): - connect_two_way(world, 'Old Man Cave (West)', 'Old Man Cave Exit (West)', player) - else: - connect_two_way(world, 'Bumper Cave (Bottom)', 'Old Man Cave Exit (West)', player) - + random.shuffle(lw_wdm_entrances) + old_man_entrance = lw_wdm_entrances.pop() + connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) + # connect remaining LW DM entrances if 0x03 in world.owswaps[player][0] == 0x05 in world.owswaps[player][0]: # if WDM and EDM are in same world connect_caves(world, lw_wdm_entrances + lw_edm_entrances, [], caves, player) @@ -2231,20 +2196,6 @@ default_dropexit_connections = [('Lost Woods Hideout Stump', 'Lost Woods Hideout #('Pyramid Entrance', 'Pyramid Exit') # this is dynamically added because of Inverted/OW Mixed ] -swapped_connections = { - 0x03: [ - ('Old Man Cave (East)', 'Death Mountain Return Cave Exit (West)'), - #('Death Mountain Return Cave (East)', 'Death Mountain Return Cave Exit (East)'), - ('Dark Death Mountain Fairy', 'Old Man Cave Exit (East)') - ], - 0x0a: [ - ('Old Man Cave (West)', 'Bumper Cave Exit (Bottom)'), - ('Death Mountain Return Cave (West)', 'Bumper Cave Exit (Top)'), - ('Bumper Cave (Bottom)', 'Old Man Cave Exit (West)'), - ('Bumper Cave (Top)', 'Dark Death Mountain Healer Fairy') - ] -} - open_default_connections = [('Links House', 'Links House Exit'), ('Big Bomb Shop', 'Big Bomb Shop') ] diff --git a/OWEdges.py b/OWEdges.py index fc307d8c..d4f5f8a1 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -991,7 +991,7 @@ OWTileGroups = { 0x42 ] ), - ("West Mountain", "Regular", "None"): ( + ("Mountain Entry", "Entrance", "None"): ( [ 0x03 ], From fb482729a876ee8e0a4674da95c86c7c0fbfa815 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 12 Jan 2022 03:24:51 -0600 Subject: [PATCH 17/73] Flute start if Kakariko Village in opposite world --- ItemList.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ItemList.py b/ItemList.py index 14a0b933..2a07172e 100644 --- a/ItemList.py +++ b/ItemList.py @@ -266,7 +266,7 @@ def generate_itempool(world, player): (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_total, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray[player]) world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999) else: - (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player]) + (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player], world.is_tile_swapped(0x18, player)) if player in world.pool_adjustment.keys(): amt = world.pool_adjustment[player] @@ -749,7 +749,7 @@ rupee_chart = {'Rupee (1)': 1, 'Rupees (5)': 5, 'Rupees (20)': 20, 'Rupees (50)' 'Rupees (100)': 100, 'Rupees (300)': 300} -def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic): +def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic, flute_start): pool = [] placed_items = {} precollected_items = [] @@ -774,6 +774,9 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, pool.remove('Pegasus Boots') pool.extend(['Rupees (20)']) + if flute_start: + precollected_items.append('Ocarina') + if want_progressives(): pool.extend(progressivegloves) else: @@ -1022,7 +1025,7 @@ def test(): for retro in [True, False]: for door_shuffle in ['basic', 'crossed', 'vanilla']: for bombbag in [True, False]: - out = get_pool_core(progressive, shuffle, difficulty, 30, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic) + out = get_pool_core(progressive, shuffle, difficulty, 30, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic, False) count = len(out[0]) + len(out[1]) correct_count = total_items_to_place From f083a410456a6bbf5cecfd8ef4f85e9f17222423 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 13 Jan 2022 19:37:08 -0600 Subject: [PATCH 18/73] Minor ER fix for extra starting locations to work correctly --- Rom.py | 2 +- data/base2current.bps | Bin 87371 -> 87377 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index 55a9346e..46e863be 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '828431c06c6c17d4e30d821cfadb70fa' +RANDOMIZERBASEHASH = 'e57c15f7a80a8e65d0c50c9eec99f072' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index d52ac3cc59e1e786f2a12cb9857daf089524ad36..0efee8a4430ba3aa5719033ec839df7db1d7dae2 100644 GIT binary patch delta 811 zcmWN`T})GF90u_7Z+l8x3RECf48!gi1*-@uDyGE%$)qYOh(r^)Fh)h_#P5NYo{y3` z8$!Qd#6qA{^SqZ{IddSS%G3(L)d5wV7|Au4;Ho8Ob?8H>;_BJ|Cl zK$HLdCE%^F2w)x`R2c#O#mCh{bW%kk#A}#woTsk>-Gxt~RYHJyhIm7MDtVa9snBm- z=%nR4|M0rTnML%K0ppv~>07Sbx3iWj6n{SabOd?`8DC5FRrb)#j4P zkS6G3TK|z2XJ7D5PEMLU{<@3kLxv4r;uV>-xsZuD+cAJT{K0;t2=3!OCu{UZzatVW z^>nX0?Du^`L+AJH+P$DNAU2M$v4g{vMIE=AM%XY#6@Mg)__O>+yFVbFAm?u6=CcH` zlB}g8Y)_}Qr%M~RMF0NGMq(A7Lb0ogduU;fv<;vd*D^Kz;}_&|t$}Rxrz;0mqGztt z>6-VUx|8oi;ZzawsIUf64^VY$IRw$~t*Z+b)Xd*<7)XjIpbd^50;&8M64X*|84?_F z@v?dUA@!oeDs1MjgbpzM=u_(tz@ap^nKmwb?R|@^ZY$KFTDP6EPB{lDOZ`V@tn?Af zT>q{LHssBqCYvHR+Z6N*kt4FiB)fvNc12DjrV|txeA8l^lJ(y2CF zZ95fj`t3_?*UvQxfdhloH7bS+PYK?Kh20svcP`O=wf)ZJh%kp7jG2GSDI=Y+6PCgxM?~JeUww$j(s=M zQj&MJ@P5;%=6Q1eY21HrzZOdHeC#Qx)a&us$m}M1)hR)8;?cPmdMJ`)8p_u cDgY@(2aM|c`r$P?NZ+B;KY5q#zS#Wre`>5}LI3~& delta 824 zcmWN~YfM{Z00!Xmo%TR!fmJ#SmMUilnS{Anw`QBRC^XSs!VH%xWbV@Zr<=5sSyqcLq)dh_}<6ezCD+HJs$ZNM3 zKN6rQ3a0tP#v|B+1N^5^4!3w%r^oTTVejwNO1}{HV^YN6Av3_S#U-*C@U^a4c z6s7cqD&ww9L>(Sr+`mgE^G5@jOh)hZJ6U+&U<0>M_2$=~0b0b`P5{u1?%Ut7g6pW| z{gwjV=lkQyIbk zJT^m52k+s<23*%ovm?WKBf-2heU(V=^IF7UBR50CH~Xqo+)Iz3(Dyv8sapS)?zdzM zQz`wD^U74YGci@3wtR9BpZ8m&QussP>5}zK#QE-0BvvefY9gkF$G?WHZU+d!kb4K| zX@)7c`LU;~HvGp_Wt}84@}rSYQW2|&12{2W!D%%A6;=J>%L`~YyXkquIe>-#HPq^+Z5P=bz!@)r?EZQKI~bn z%C11tuE;v97HhzkV9T*4Y$cYlE7B&{!l*v0YM_@BS;^eB5D>GoY$7KY3;x_JG_r%> zD2%e(i&|{T&@kUUcAntFHSlM)O-r?=hn(Z<`Eom~=XUD2QOOz|(A^-y<&fnn>chGC z#l#5Q*`!3TBr2K|UpN=K=u6Y`?$;Dw$&K^<*E&xMf%Y-tQzD7XJ%Vq>5;E|<)m-T6 z;FlNT!YcfQqd_O!;3|!W*Mu`+uW&~6hIg%ry?-u$m^WcqgnRjaHQb{0iN(sF45(Ic zY}0pj4UXMziw@~b6TOMda)Hf+Wp0c9(>Azl} y%6bH;70vxUUjS(75(VmkWpa@M&ygTsGH3up61yk&Xh6v!%@&7e%fr&&9{(RyLvcR< From af00bdec1ef992d5cd89372b5dad5be775c9bc16 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 13 Jan 2022 19:49:08 -0600 Subject: [PATCH 19/73] Start in BBS in Inverted, replacing LH/BBS entrance swap --- BaseClasses.py | 2 +- DoorShuffle.py | 5 +- EntranceShuffle.py | 138 ++++++++++++++++++++++----------------------- Regions.py | 2 +- Rom.py | 42 ++++++++++++-- 5 files changed, 109 insertions(+), 80 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 752b96ae..724410c6 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1661,7 +1661,7 @@ class Entrance(object): # this is checked first as this often the shortest path follower_region = start_region if follower_region.type not in [RegionType.LightWorld, RegionType.DarkWorld]: - follower_region = start_region.entrances[0].parent_region + follower_region = [i for i in start_region.entrances if i.parent_region.name != 'Menu'][0].parent_region if (follower_region.world.mode[self.player] != 'inverted') == (follower_region.type == RegionType.LightWorld): from OWEdges import OWTileRegions from OverworldShuffle import ow_connections diff --git a/DoorShuffle.py b/DoorShuffle.py index fcd312cd..b55d2f6a 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1815,10 +1815,7 @@ def remove_pair_type_if_present(door, world, player): def find_inaccessible_regions(world, player): world.inaccessible_regions[player] = [] - if world.mode[player] != 'inverted': - start_regions = ['Links House', 'Sanctuary'] - else: - start_regions = ['Links House', 'Dark Sanctuary Hint'] + start_regions = ['Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint'] regs = convert_regions(start_regions, world, player) all_regions = [r for r in world.regions if r.player == player and r.type is not RegionType.Dungeon] visited_regions = set() diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 8f92644d..acd6adc6 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -54,33 +54,33 @@ def link_entrances(world, player): for exitname, regionname in mandatory_connections: connect_simple(world, exitname, regionname, player) - if not invFlag: - for exitname, regionname in open_mandatory_connections: - connect_simple(world, exitname, regionname, player) + if not world.is_tile_swapped(0x2c, player): + connect_simple(world, 'Links House S&Q', 'Links House', player) else: - for exitname, regionname in inverted_mandatory_connections: - connect_simple(world, exitname, regionname, player) + connect_simple(world, 'Links House S&Q', 'Big Bomb Shop', player) + + if not invFlag: + connect_simple(world, 'Sanctuary S&Q', 'Sanctuary', player) + else: + connect_simple(world, 'Sanctuary S&Q', 'Dark Sanctuary Hint', player) connect_simple(world, 'Tavern North', 'Tavern', player) + suppress_spoiler = False connect_custom(world, player) + suppress_spoiler = True # if we do not shuffle, set default connections if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: for entrancename, exitname in default_connections + drop_connections + default_item_connections + default_shop_connections: - connect_logical(world, entrancename, exitname, player, False) + connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit')) for entrancename, exitname in default_connector_connections + dropexit_connections: connect_logical(world, entrancename, exitname, player, True) if invFlag: world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance('Dark Sanctuary Hint', player).parent_region) + if world.is_tile_swapped(0x2c, player): + world.get_entrance('Big Bomb Shop Exit', player).connect(world.get_entrance('Big Bomb Shop', player).parent_region) - if not invFlag: - for entrancename, exitname in open_default_connections: - connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit')) - else: - for entrancename, exitname in inverted_default_connections: - connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit')) - ignore_pool = False # dungeon entrance shuffle @@ -215,11 +215,12 @@ def link_entrances(world, player): junk_fill_inaccessible(world, player) # place bomb shop, has limited options - bomb_shop_doors = list(entrance_pool) - if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): - bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] - bomb_shop = random.choice(bomb_shop_doors) - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + if not world.is_tile_swapped(0x2c, player): + bomb_shop_doors = list(entrance_pool) + if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): + bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + bomb_shop = random.choice(bomb_shop_doors) + connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) # place remaining doors connect_doors(world, list(entrance_pool), list(exit_pool), player) @@ -260,11 +261,12 @@ def link_entrances(world, player): place_old_man(world, lw_entrances if not invFlag else dw_entrances, player) # place bomb shop, has limited options - bomb_shop_doors = list(entrance_pool) - if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): - bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] - bomb_shop = random.choice(bomb_shop_doors) - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + if not world.is_tile_swapped(0x2c, player): + bomb_shop_doors = list(entrance_pool) + if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): + bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + bomb_shop = random.choice(bomb_shop_doors) + connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) # shuffle connectors lw_entrances = [e for e in lw_entrances if e in entrance_pool] @@ -317,11 +319,12 @@ def link_entrances(world, player): place_old_man(world, lw_entrances if not invFlag else dw_entrances, player, list(zip(*drop_connections + dropexit_connections))[0]) # place bomb shop, has limited options - bomb_shop_doors = [e for e in entrance_pool if e not in list(zip(*drop_connections + dropexit_connections))[0]] - if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): - bomb_shop_doors = [e for e in bomb_shop_doors if e not in ['Pyramid Fairy']] - bomb_shop = random.choice(bomb_shop_doors) - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + if not world.is_tile_swapped(0x2c, player): + bomb_shop_doors = [e for e in entrance_pool if e not in list(zip(*drop_connections + dropexit_connections))[0]] + if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): + bomb_shop_doors = [e for e in bomb_shop_doors if e not in ['Pyramid Fairy']] + bomb_shop = random.choice(bomb_shop_doors) + connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) # shuffle connectors lw_entrances = [e for e in lw_entrances if e in entrance_pool] @@ -419,11 +422,12 @@ def link_entrances(world, player): connect_caves(world, lw_entrances, dw_entrances, caves, player) # place bomb shop, has limited options - bomb_shop_doors = list(entrance_pool) - if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): - bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] - bomb_shop = random.choice(bomb_shop_doors) - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + if not world.is_tile_swapped(0x2c, player): + bomb_shop_doors = list(entrance_pool) + if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): + bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + bomb_shop = random.choice(bomb_shop_doors) + connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) # place remaining doors connect_doors(world, list(entrance_pool), list(exit_pool), player) @@ -473,11 +477,12 @@ def link_entrances(world, player): connect_caves(world, connector_entrances, [], caves, player) # place bomb shop, has limited options - bomb_shop_doors = list(entrance_pool) - if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): - bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] - bomb_shop = random.choice(bomb_shop_doors) - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + if not world.is_tile_swapped(0x2c, player): + bomb_shop_doors = list(entrance_pool) + if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): + bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + bomb_shop = random.choice(bomb_shop_doors) + connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) # place remaining doors connect_doors(world, list(entrance_pool), list(exit_pool), player) @@ -522,11 +527,12 @@ def link_entrances(world, player): place_old_man(world, pool, player) # place bomb shop, has limited options - bomb_shop_doors = list(entrance_pool) - if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): - bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] - bomb_shop = random.choice(bomb_shop_doors) - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + if not world.is_tile_swapped(0x2c, player): + bomb_shop_doors = list(entrance_pool) + if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): + bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + bomb_shop = random.choice(bomb_shop_doors) + connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) # shuffle connectors pool = [e for e in pool if e in entrance_pool] @@ -605,13 +611,14 @@ def link_entrances(world, player): caves.append('Old Man Cave Exit (West)') # place bomb shop, has limited options - bomb_shop_doors = list(entrance_pool) - if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): - bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] - random.shuffle(bomb_shop_doors) - bomb_shop = bomb_shop_doors.pop() - pool.remove(bomb_shop) - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) + if not world.is_tile_swapped(0x2c, player): + bomb_shop_doors = list(entrance_pool) + if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): + bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + random.shuffle(bomb_shop_doors) + bomb_shop = bomb_shop_doors.pop() + pool.remove(bomb_shop) + connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) # shuffle connectors doors = list(entrance_pool) @@ -635,8 +642,8 @@ def link_entrances(world, player): # ensure Houlihan exits where Links House does # TODO: Plando should overrule this if not links_house: - for links_house in world.get_entrance('Links House Exit', player).connected_region.exits: - if links_house.connected_region and links_house.connected_region.name == 'Links House': + for links_house in world.get_entrance('Links House Exit' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop Exit', player).connected_region.exits: + if links_house.connected_region and links_house.connected_region.name == ('Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop'): links_house = links_house.name break connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) @@ -1335,7 +1342,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player): def place_links_house(world, player, ignore_list=[]): invFlag = world.mode[player] == 'inverted' if world.mode[player] == 'standard' or not world.shufflelinks[player]: - links_house = 'Links House' if not invFlag else 'Big Bomb Shop' + links_house = 'Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop' else: if invFlag: for dark_sanc in world.get_entrance('Dark Sanctuary Hint Exit', player).connected_region.exits: @@ -1354,7 +1361,11 @@ def place_links_house(world, player, ignore_list=[]): links_house_doors = [e for e in links_house_doors if e not in ignore_list] assert len(links_house_doors), 'No valid candidates to place Links House' links_house = random.choice(links_house_doors) - connect_two_way(world, links_house, 'Links House Exit', player) + if not world.is_tile_swapped(0x2c, player): + connect_two_way(world, links_house, 'Links House Exit', player) + else: + connect_entrance(world, links_house, 'Big Bomb Shop', player) + world.get_entrance('Big Bomb Shop Exit', player).connect(world.get_entrance(links_house, player).parent_region) return links_house @@ -2037,8 +2048,7 @@ Exit_Pool_Base = ['Links House Exit', 'Pyramid'] # these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions -mandatory_connections = [('Links House S&Q', 'Links House'), - ('Old Man S&Q', 'Old Man House'), +mandatory_connections = [('Old Man S&Q', 'Old Man House'), # UW Connections ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), @@ -2069,10 +2079,6 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Ganon Drop', 'Bottom of Pyramid') ] -open_mandatory_connections = [('Sanctuary S&Q', 'Sanctuary')] - -inverted_mandatory_connections = [('Sanctuary S&Q', 'Dark Sanctuary Hint')] - # non-shuffled entrance links default_connections = [('Lumberjack House', 'Lumberjack House'), ('Bonk Fairy (Light)', 'Bonk Fairy (Light)'), @@ -2137,7 +2143,8 @@ default_connector_connections = [('Old Man Cave (West)', 'Old Man Cave Exit (Wes ('Hookshot Cave Back Entrance', 'Hookshot Cave Back Exit') ] -default_item_connections = [('Mimic Cave', 'Mimic Cave'), +default_item_connections = [('Links House', 'Links House Exit'), + ('Mimic Cave', 'Mimic Cave'), ('Waterfall of Wishing', 'Waterfall of Wishing'), ('Bonk Rock Cave', 'Bonk Rock Cave'), ('Graveyard Cave', 'Graveyard Cave'), @@ -2161,6 +2168,7 @@ default_item_connections = [('Mimic Cave', 'Mimic Cave'), ('Brewery', 'Brewery'), ('Pyramid Fairy', 'Pyramid Fairy'), ('Dark World Hammer Peg Cave', 'Dark World Hammer Peg Cave'), + ('Big Bomb Shop', 'Big Bomb Shop'), ('Mire Shed', 'Mire Shed'), ('Hype Cave', 'Hype Cave') ] @@ -2196,14 +2204,6 @@ default_dropexit_connections = [('Lost Woods Hideout Stump', 'Lost Woods Hideout #('Pyramid Entrance', 'Pyramid Exit') # this is dynamically added because of Inverted/OW Mixed ] -open_default_connections = [('Links House', 'Links House Exit'), - ('Big Bomb Shop', 'Big Bomb Shop') - ] - -inverted_default_connections = [('Big Bomb Shop', 'Links House Exit'), - ('Links House', 'Big Bomb Shop') - ] - # non shuffled dungeons default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert Palace Exit (South)'), ('Desert Palace Entrance (West)', 'Desert Palace Exit (West)'), diff --git a/Regions.py b/Regions.py index 0dd69282..47864ca1 100644 --- a/Regions.py +++ b/Regions.py @@ -326,7 +326,7 @@ def create_regions(world, player): create_cave_region(player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']), create_cave_region(player, 'Archery Game', 'a game of skill'), create_cave_region(player, 'Bonk Fairy (Dark)', 'a fairy fountain'), - create_cave_region(player, 'Big Bomb Shop', 'the bomb shop', ['Big Bomb']), + create_cave_region(player, 'Big Bomb Shop', 'the bomb shop', ['Big Bomb'], ['Big Bomb Shop Exit']), create_cave_region(player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'), create_cave_region(player, 'East Dark World Hint', 'a storyteller'), create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left', diff --git a/Rom.py b/Rom.py index 46e863be..684a2022 100644 --- a/Rom.py +++ b/Rom.py @@ -800,7 +800,10 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): if should_be_bunny(sanc_region, world.mode[player]): rom.write_bytes(0x13fff2, [0x12, 0x00]) - lh_name = 'Links House' + if not world.is_tile_swapped(0x2c, player): + lh_name = 'Links House' + else: + lh_name = 'Big Bomb Shop' links_house = world.get_region(lh_name, player) if should_be_bunny(links_house, world.mode[player]): rom.write_bytes(0x13fff0, [0x04, 0x01]) @@ -2625,10 +2628,24 @@ def set_inverted_mode(world, player, rom, inverted_buffer): if world.is_tile_swapped(0x29, player): rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact if world.is_tile_swapped(0x2c, player): - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - rom.write_byte(0x15B8C, 0x6C) # exit links at bomb shop area - rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house - rom.write_byte(0xDBB73 + 0x52, 0x01) + rom.write_bytes(snes_to_pc(0x03F484), [0xFD, 0x4B, 0x68]) # place bed in bomb shop + + # spawn in bomb shop + patch_shuffled_bomb_shop(world, rom, player) + rom.write_byte(snes_to_pc(0x02D8D2), 0x1C) + rom.write_bytes(snes_to_pc(0x02D8E0), [0x23, 0x22, 0x23, 0x23, 0x18, 0x18, 0x18, 0x19]) + rom.write_byte(snes_to_pc(0x02D919), 0x18) + rom.write_byte(snes_to_pc(0x02D927), 0x23) + write_int16(rom, snes_to_pc(0x02D934), 0x2398) + rom.write_byte(snes_to_pc(0x02D943), 0x18) + write_int16(rom, snes_to_pc(0x02D950), 0x0087) + write_int16(rom, snes_to_pc(0x02D95E), 0x0081) + rom.write_byte(snes_to_pc(0x02D9A4), 0x53) + + # disable custom exit on links house exit + rom.write_byte(snes_to_pc(0x02E225), 0x1C) + rom.write_byte(snes_to_pc(0x02DAEE), 0x1C) + rom.write_byte(snes_to_pc(0x02DB8C), 0x6C) if world.is_tile_swapped(0x2f, player): rom.write_bytes(snes_to_pc(0x1BC80D), [0xB2, 0x0B, 0x82]) # add warp under rock rom.write_byte(snes_to_pc(0x1BC590), 0x00) # remove secret portal @@ -2661,6 +2678,21 @@ def patch_shuffled_dark_sanc(world, rom, player): rom.write_bytes(0x180262, [unknown_1, unknown_2, 0x00]) +def patch_shuffled_bomb_shop(world, rom, player): + bomb_shop = world.get_region('Big Bomb Shop', player) + bomb_shop_entrance = str([i for i in bomb_shop.entrances if i.parent_region.name != 'Menu'][0].name) + room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2 = door_addresses[bomb_shop_entrance][1] + door_index = door_addresses[str(bomb_shop_entrance)][0] + + rom.write_byte(0x180240, 0x02) + rom.write_byte(0x180247, door_index + 1) + write_int16(rom, 0x180264, room_id) + rom.write_byte(0x180266, ow_area) + write_int16s(rom, 0x180267, [vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x]) + rom.write_bytes(0x180275, [unknown_1, unknown_2, 0x00]) + write_int16(rom, snes_to_pc(0x02D996), door_1) + + def update_compasses(rom, world, player): layouts = world.dungeon_layouts[player] provided_dungeon = False From 9282d84fd675dac6b6596cd8d4010cf610b29873 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 13 Jan 2022 22:11:27 -0600 Subject: [PATCH 20/73] Preopened OW doors when starting location exits there --- BaseClasses.py | 2 + EntranceShuffle.py | 262 +++++++++++++++++++++--------------------- Rom.py | 6 +- data/base2current.bps | Bin 87377 -> 87380 bytes 4 files changed, 137 insertions(+), 133 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 724410c6..6446bb5e 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -61,6 +61,7 @@ class World(object): self.lock_aga_door_in_escape = False self.save_and_quit_from_boss = True self.accessibility = accessibility.copy() + self.initial_overworld_flags = {} self.fix_skullwoods_exit = {} self.fix_palaceofdarkness_exit = {} self.fix_trock_exit = {} @@ -118,6 +119,7 @@ class World(object): set_player_attr('ganon_at_pyramid', True) set_player_attr('ganonstower_vanilla', True) set_player_attr('sewer_light_cone', self.mode[player] == 'standard') + set_player_attr('initial_overworld_flags', [0] * 0x80) set_player_attr('fix_trock_doors', self.shuffle[player] != 'vanilla' or ((self.mode[player] == 'inverted') != 0x05 in self.owswaps[player][0])) set_player_attr('fix_skullwoods_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] or self.doorShuffle[player] not in ['vanilla']) set_player_attr('fix_palaceofdarkness_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index acd6adc6..826dc585 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -2318,155 +2318,153 @@ indirect_connections = { } # format: # Key=Name -# addr = (door_index, exitdata) # multiexit +# addr = (door_index, exitdata, ow_flag) # multiexit # | ([addr], None) # holes # exitdata = (room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2) # ToDo somehow merge this with creation of the locations - -# ToDo somehow merge this with creation of the locations -door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000)), - 'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000)), - 'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000)), - 'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000)), - 'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), - 'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000)), - 'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be)), - 'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124)), - 'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158)), - 'Inverted Pyramid Entrance': (0x35, (0x0010, 0x1b, 0x000e, 0x0600, 0x0676, 0x0604, 0x06e8, 0x066d, 0x06f3, 0x00, 0x0a, 0x0000, 0x811c)), - 'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be)), - 'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000)), - 'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000)), - 'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000)), - 'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000)), - 'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000)), - 'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000)), - 'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), - 'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000)), - 'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000)), - 'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000)), - 'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000)), - 'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000)), - 'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000)), - 'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000)), - 'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000)), - 'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000)), - 'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000)), - 'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000)), - 'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000)), - 'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa)), - 'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000)), - 'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000)), - 'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000)), - 'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000)), - 'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000)), - 'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), - 'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), - 'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000)), - 'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), - 'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000)), - 'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000)), - 'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), - 'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000)), - 'Ganons Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000)), - 'Pyramid Entrance': (0x35, (0x0010, 0x5b, 0x0b0e, 0x075a, 0x0674, 0x07a8, 0x06e8, 0x07c7, 0x06f3, 0x06, 0xfa, 0x0000, 0x0000)), +door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000), 0x00), + 'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000), 0x00), + 'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000), 0x00), + 'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000), 0x00), + 'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000), 0x00), + 'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000), 0x00), + 'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000), 0x00), + 'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be), 0x00), + 'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124), 0x00), + 'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158), 0x00), + 'Inverted Pyramid Entrance': (0x35, (0x0010, 0x1b, 0x000e, 0x0600, 0x0676, 0x0604, 0x06e8, 0x066d, 0x06f3, 0x00, 0x0a, 0x0000, 0x811c), 0x00), + 'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be), 0x40), + 'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000), 0x00), + 'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000), 0x00), + 'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000), 0x00), + 'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000), 0x20), + 'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000), 0x00), + 'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000), 0x20), + 'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000), 0x20), + 'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000), 0x00), + 'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000), 0x00), + 'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000), 0x00), + 'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000), 0x00), + 'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000), 0x00), + 'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000), 0x00), + 'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000), 0x00), + 'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000), 0x00), + 'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000), 0x00), + 'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000), 0x00), + 'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000), 0x00), + 'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000), 0x00), + 'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa), 0x00), + 'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000), 0x00), + 'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000), 0x00), + 'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000), 0x00), + 'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000), 0x00), + 'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000), 0x00), + 'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000), 0x00), + 'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000), 0x00), + 'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000), 0x00), + 'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000), 0x00), + 'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000), 0x00), + 'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000), 0x20), + 'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000), 0x00), + 'Ganons Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000), 0x20), + 'Pyramid Entrance': (0x35, (0x0010, 0x5b, 0x0b0e, 0x075a, 0x0674, 0x07a8, 0x06e8, 0x07c7, 0x06f3, 0x06, 0xfa, 0x0000, 0x0000), 0x00), 'Skull Woods First Section Hole (West)': ([0xDB84D, 0xDB84E], None), 'Skull Woods First Section Hole (East)': ([0xDB84F, 0xDB850], None), 'Skull Woods First Section Hole (North)': ([0xDB84C], None), 'Skull Woods Second Section Hole': ([0xDB851, 0xDB852], None), 'Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856], None), 'Inverted Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856, 0x180340], None), - 'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), - 'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000)), - 'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000)), + 'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000), 0x00), 'Hyrule Castle Secret Entrance Drop': ([0xDB858], None), - 'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000)), - 'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), - 'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000)), - 'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x08f9, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000)), # do not use, buggy - 'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000)), - 'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000)), - 'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000)), - 'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000), 0x02), + 'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000), 0x20), + 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x08f9, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000), 0x00), # do not use, buggy + 'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000), 0x00), + 'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000), 0x00), + 'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), 'Kakariko Well Drop': ([0xDB85C, 0xDB85D], None), - 'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000)), + 'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000), 0x00), 'Bat Cave Drop': ([0xDB859, 0xDB85A], None), - 'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000)), + 'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000), 0x00), 'North Fairy Cave Drop': ([0xDB857], None), - 'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000)), - 'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000)), - 'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000)), - 'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000)), - 'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000)), - 'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000)), - 'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000)), + 'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000), 0x00), + 'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000), 0x00), + 'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000), 0x00), + 'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000), 0x00), + 'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000), 0x02), + 'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000), 0x00), 'Lost Woods Hideout Drop': ([0xDB853], None), 'Lumberjack Tree Tree': ([0xDB85B], None), - 'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000)), - 'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000)), - 'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000)), - 'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000)), - 'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), - '20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000)), - '50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000)), - 'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), - 'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000)), - 'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000)), - 'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000)), + 'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000), 0x00), + 'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000), 0x02), + 'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000), 0x00), + '20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000), 0x20), + '50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x02), + 'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000), 0x00), + 'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000), 0x00), 'Sanctuary Grave': ([0xDB85E], None), - 'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000)), - 'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), - 'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), - 'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000)), - 'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), - 'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000)), - 'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000)), - 'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000)), - 'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000)), - 'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000)), - 'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000)), - 'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000)), - 'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000)), - 'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000)), - 'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000)), - 'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000)), - 'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000)), - 'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000)), - 'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000)), - 'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000))} + 'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00), + 'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000), 0x02), + 'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x02), + 'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000), 0x20), + 'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000), 0x02), + 'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000), 0x20), + 'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000), 0x02), + 'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000), 0x00), + 'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000), 0x00), + 'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000), 0x20), + 'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000), 0x00), + 'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000), 0x00), + 'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00), + 'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000), 0x00), + 'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000), 0x00), + 'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00), + 'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00), + 'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000), 0x00), + 'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000), 0x00), + 'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00)} # format: # Key=Name diff --git a/Rom.py b/Rom.py index 684a2022..a928cb98 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'e57c15f7a80a8e65d0c50c9eec99f072' +RANDOMIZERBASEHASH = '7f50c5e64c151af842e5887c69ac9cfc' class JsonRom(object): @@ -1433,6 +1433,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): assert equip[:0x340] == [0] * 0x340 rom.write_bytes(0x183000, equip[0x340:]) rom.write_bytes(0x271A6, equip[0x340:0x340+60]) + + rom.write_bytes(0x183080, world.initial_overworld_flags[player]) # starting overworld flags rom.write_byte(0x18004A, 0x00 if world.mode[player] != 'inverted' else 0x01) # Inverted mode rom.write_byte(0x18005D, 0x00) # Hammer always breaks barrier @@ -2669,6 +2671,7 @@ def patch_shuffled_dark_sanc(world, rom, player): dark_sanc_entrance = str([i for i in dark_sanc.entrances if i.parent_region.name != 'Menu'][0].name) room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2 = door_addresses[dark_sanc_entrance][1] door_index = door_addresses[str(dark_sanc_entrance)][0] + world.initial_overworld_flags[player][ow_area] |= door_addresses[dark_sanc_entrance][2] rom.write_byte(0x180241, 0x01) rom.write_byte(0x180248, door_index + 1) @@ -2683,6 +2686,7 @@ def patch_shuffled_bomb_shop(world, rom, player): bomb_shop_entrance = str([i for i in bomb_shop.entrances if i.parent_region.name != 'Menu'][0].name) room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2 = door_addresses[bomb_shop_entrance][1] door_index = door_addresses[str(bomb_shop_entrance)][0] + world.initial_overworld_flags[player][ow_area] |= door_addresses[bomb_shop_entrance][2] rom.write_byte(0x180240, 0x02) rom.write_byte(0x180247, door_index + 1) diff --git a/data/base2current.bps b/data/base2current.bps index 0efee8a4430ba3aa5719033ec839df7db1d7dae2..cc60f92774883d67ae8863d4989decb91c7f555c 100644 GIT binary patch delta 4570 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

2B#UWh^ zj2LVH2)s4u3lhw)2i2TO%(-1W42jRmOnjDILWeNJ+w<_hc}WW9e7$^uLdycSP)m_8XS(^T|6T##I4jjlxLQsK zlItyv%vYjk#PC*h70iD#3d}Q?y(!>>eMA5kj2perN)6{qthD{Pb*%mAuzud`XNuf8 z5+a$%;DSQlTCSZ)Z5rT$6pp}qhDx&t4GecD);7iQ!E0CNg}$2XU1c*xn!u(wZ&2>W z%X6uJmfF-e7Ie9CbsKk75p~l*bj;XU{^%;Dm$oUr0e*Zor`N}nNd9bJ>ns_xAB)in-?L2+OKSFNUvhy^NG7tEV*7?u9Ts3p^ z5xlKU+ delta 4609 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 From 14d670e3ec5407426f596b36659ec5c1ea02159d Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 13 Jan 2022 22:30:34 -0600 Subject: [PATCH 21/73] Start in BBS in Inverted, replacing LH/BBS entrance swap --- DoorShuffle.py | 10 ++++------ OverworldShuffle.py | 6 +++++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index b55d2f6a..17fda12c 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1833,7 +1833,7 @@ def find_inaccessible_regions(world, player): if connect and connect not in queue and connect not in visited_regions: if connect.type is not RegionType.Dungeon or connect.name.endswith(' Portal'): queue.append(connect) - world.inaccessible_regions[player].extend([r.name for r in all_regions if r not in visited_regions and valid_inaccessible_region(r)]) + world.inaccessible_regions[player].extend([r.name for r in all_regions if r not in visited_regions and valid_inaccessible_region(world, r, player)]) if world.is_tile_swapped(0x1b, player): ledge = world.get_region('Hyrule Castle Ledge', player) if any(x for x in ledge.exits if x.connected_region and x.connected_region.name == 'Agahnims Tower Portal'): @@ -1850,10 +1850,8 @@ def find_accessible_entrances(world, player, builder): if world.mode[player] == 'standard' and builder.name == 'Hyrule Castle': start_regions = ['Hyrule Castle Courtyard'] - elif world.mode[player] != 'inverted': - start_regions = ['Links House', 'Sanctuary'] else: - start_regions = ['Links House', 'Dark Sanctuary Hint'] + start_regions = ['Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint'] if world.is_tile_swapped(0x1b, player): start_regions.append('Hyrule Castle Ledge') regs = convert_regions(start_regions, world, player) @@ -1887,8 +1885,8 @@ def find_accessible_entrances(world, player, builder): return visited_entrances -def valid_inaccessible_region(r): - return r.type is not RegionType.Cave or (len(r.exits) > 0 and r.name not in ['Links House', 'Chris Houlihan Room']) +def valid_inaccessible_region(world, r, player): + return r.type is not RegionType.Cave or (len(r.exits) > 0 and r.name not in ['Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop', 'Chris Houlihan Room']) def add_inaccessible_doors(world, player): diff --git a/OverworldShuffle.py b/OverworldShuffle.py index ff663e13..85d62b82 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -841,7 +841,11 @@ def can_reach_smith(world, player): found = False explored_regions = list() - explore_region('Links House') + if not world.is_tile_swapped(0x2c, player): + start_region = 'Links House' + else: + start_region = 'Big Bomb Shop' + explore_region(start_region) if not found: if not invFlag: explore_region('Sanctuary') From 770ac319452a7918f982227fa14a334e18cad81d Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 14 Jan 2022 13:01:45 -0600 Subject: [PATCH 22/73] Reorganized starting data tables --- Rom.py | 10 ++++++---- data/base2current.bps | Bin 87380 -> 87381 bytes 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Rom.py b/Rom.py index a928cb98..a8c6a4f3 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '7f50c5e64c151af842e5887c69ac9cfc' +RANDOMIZERBASEHASH = '57e05a3a24204d6083d293dbd04da991' class JsonRom(object): @@ -1275,6 +1275,10 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x180174, 0x01 if world.fix_fake_world[player] else 0x00) rom.write_byte(0x18017E, 0x01) # Fairy fountains only trade in bottles + # starting overworld flags + assert len(world.initial_overworld_flags[player]) == 0x80 and all([i < 0x100 for i in world.initial_overworld_flags[player]]) + rom.write_bytes(0x183280, world.initial_overworld_flags[player]) + # Starting equipment if world.pseudoboots[player]: rom.write_byte(0x18008E, 0x01) @@ -1431,11 +1435,9 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x180043, equip[0x359]) assert equip[:0x340] == [0] * 0x340 - rom.write_bytes(0x183000, equip[0x340:]) + rom.write_bytes(0x183340, equip[0x340:]) rom.write_bytes(0x271A6, equip[0x340:0x340+60]) - rom.write_bytes(0x183080, world.initial_overworld_flags[player]) # starting overworld flags - rom.write_byte(0x18004A, 0x00 if world.mode[player] != 'inverted' else 0x01) # Inverted mode rom.write_byte(0x18005D, 0x00) # Hammer always breaks barrier rom.write_byte(0x03A943, 0xD0 if world.mode[player] != 'inverted' else 0xF0) # Mirror: Normal (D0=Dark to Light, F0=light to dark, 42 = both) diff --git a/data/base2current.bps b/data/base2current.bps index cc60f92774883d67ae8863d4989decb91c7f555c..b11b9c359246ca458ae06f9ecd0349cf34b06a11 100644 GIT binary patch delta 86 zcmV-c0IC1fss+`m1+YZ{1b5?z9J5IQCawyMvoMd018}d7vy*wRkODxnlMApi0kX3` sus?Yg1%OgB4}gUj7^-X{xfg+1OpOEKN*cG4DFM1G2yQ2&(`3>9Q}?bS?EnA( delta 85 zcmV-b0IL7hss+@l1+YZ{1VZG!8?#9PCawxhurQB|18}cSu#n=eNfQ1+ss%#>;7lAcRj|2Nk4Y!ji0lF&)j3ij4V8HziyoVvB From dab0c16d7e765edff34561d5698ce3590d39823d Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 04:08:28 -0600 Subject: [PATCH 23/73] Added flute SFX to itemget if collecting a pre-activated flute --- Rom.py | 2 +- data/base2current.bps | Bin 87381 -> 87435 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index a8c6a4f3..42d13f2d 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '57e05a3a24204d6083d293dbd04da991' +RANDOMIZERBASEHASH = '2fe9f5776fa383e419e6feb779e583b5' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index b11b9c359246ca458ae06f9ecd0349cf34b06a11..0c5a26337ffe2b7220ebcf7428810a2012d8952b 100644 GIT binary patch delta 2130 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 WS6)6SM04L0mPK@bx9jHb@Ba_;_>XS@ From 95bc7609e4314170eff488fcaf7540bb468dfae7 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 04:11:23 -0600 Subject: [PATCH 24/73] Added pre-activated flute to item pool in Inverted --- BaseClasses.py | 4 ++-- ItemList.py | 9 +++++---- Items.py | 1 + OverworldShuffle.py | 4 ++-- Rom.py | 9 +++++++-- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 6446bb5e..d43c8751 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1312,10 +1312,10 @@ class CollectionState(object): return self.has('Fire Rod', player) or self.has('Lamp', player) def can_flute(self, player): - if any(map(lambda i: i.name == 'Ocarina', self.world.precollected_items)): + if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], self.world.precollected_items)): return True lw = self.world.get_region('Kakariko Area', player) - return self.has('Ocarina', player) and lw.can_reach(self) and self.is_not_bunny(lw, player) + return self.has('Ocarina Activated', player) or (self.has('Ocarina', player) and lw.can_reach(self) and self.is_not_bunny(lw, player)) def can_melt_things(self, player): return self.has('Fire Rod', player) or (self.has('Bombos', player) and self.has_sword(player)) diff --git a/ItemList.py b/ItemList.py index 2a07172e..1f47506d 100644 --- a/ItemList.py +++ b/ItemList.py @@ -749,7 +749,7 @@ rupee_chart = {'Rupee (1)': 1, 'Rupees (5)': 5, 'Rupees (20)': 20, 'Rupees (50)' 'Rupees (100)': 100, 'Rupees (300)': 300} -def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic, flute_start): +def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic, flute_activated): pool = [] placed_items = {} precollected_items = [] @@ -761,6 +761,10 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, pool.extend(alwaysitems) + if flute_activated: + pool.remove('Ocarina') + pool.append('Ocarina (Activated)') + def place_item(loc, item): assert loc not in placed_items placed_items[loc] = item @@ -774,9 +778,6 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, pool.remove('Pegasus Boots') pool.extend(['Rupees (20)']) - if flute_start: - precollected_items.append('Ocarina') - if want_progressives(): pool.extend(progressivegloves) else: diff --git a/Items.py b/Items.py index 637d0b30..fd7fa0f9 100644 --- a/Items.py +++ b/Items.py @@ -31,6 +31,7 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche 'Hookshot': (True, False, None, 0x0A, 250, 'BOING!!!\nBOING!!!\nBOING!!!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'the Hookshot'), 'Magic Mirror': (True, False, None, 0x1A, 250, 'Isn\'t your\nreflection so\npretty?', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'the Mirror'), 'Ocarina': (True, False, None, 0x14, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the Flute'), + 'Ocarina (Activated)': (True, False, None, 0x4A, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the Flute'), 'Pegasus Boots': (True, False, None, 0x4B, 250, 'Gotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'the Boots'), 'Power Glove': (True, False, None, 0x1B, 100, 'Now you can\nlift weak\nstuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the glove'), 'Cape': (True, False, None, 0x19, 50, 'Wear this to\nbecome\ninvisible!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the cape'), diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 85d62b82..f298d87f 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -817,7 +817,7 @@ def can_reach_smith(world, player): region = world.get_region(region_name, player) for exit in region.exits: if not found and exit.connected_region is not None: - if any(map(lambda i: i.name == 'Ocarina', world.precollected_items)) and exit.spot_type == 'Flute': + if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], world.precollected_items)) and exit.spot_type == 'Flute': fluteregion = exit.connected_region for flutespot in fluteregion.exits: if flutespot.connected_region and flutespot.connected_region.name not in explored_regions: @@ -922,7 +922,7 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F region = base_world.get_region(region_name, player) for exit in region.exits: if exit.connected_region is not None: - if any(map(lambda i: i.name == 'Ocarina', base_world.precollected_items)) and exit.spot_type == 'Flute': + if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], base_world.precollected_items)) and exit.spot_type == 'Flute': fluteregion = exit.connected_region for flutespot in fluteregion.exits: if flutespot.connected_region and flutespot.connected_region.name not in explored_regions: diff --git a/Rom.py b/Rom.py index 42d13f2d..484b990e 100644 --- a/Rom.py +++ b/Rom.py @@ -2278,13 +2278,18 @@ def write_strings(rom, world, player, team): # Lastly we write hints to show where certain interesting items are. It is done the way it is to re-use the silver code and also to give one hint per each type of item regardless of how many exist. This supports many settings well. items_to_hint = RelevantItems.copy() + flute_item = 'Ocarina' + if world.is_tile_swapped(0x18, player): + items_to_hint.remove(flute_item) + flute_item = 'Ocarina (Activated)' + items_to_hint.append(flute_item) if world.owShuffle[player] != 'vanilla' or world.owMixed[player]: # Adding a guaranteed hint for the Flute in overworld shuffle. - this_location = world.find_items_not_key_only('Ocarina', player) + this_location = world.find_items_not_key_only(flute_item, player) if this_location: this_hint = this_location[0].item.hint_text + ' can be found ' + hint_text(this_location[0]) + '.' tt[hint_locations.pop(0)] = this_hint - items_to_hint.remove('Ocarina') + items_to_hint.remove(flute_item) if world.keyshuffle[player]: items_to_hint.extend(SmallKeys) if world.bigkeyshuffle[player]: From abdf019719aaad14ac697578ab874e1dda25a0c2 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 12:15:39 -0600 Subject: [PATCH 25/73] Changed Inverted Flute Spot 1 to Top of DDM --- OverworldShuffle.py | 4 ++-- Rom.py | 38 +++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index f298d87f..7f18f8c1 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1872,10 +1872,10 @@ isolated_regions = [ ] flute_data = { - #Slot LW Region DW Region OWID VRAM BG Y BG X Link Y Link X Cam Y Cam X Unk1 Unk2 IconY IconX AltY AltX + #Slot LW Region DW Region OWID VRAM BG Y BG X Link Y Link X Cam Y Cam X Unk1 Unk2 IconY IconX AltY AltX AltVRAM AltBGY AltBGX AltCamY AltCamX AltUnk1 AltUnk2 AltIconY AltIconX 0x09: (['Lost Woods East Area', 'Skull Woods Forest'], 0x00, 0x1042, 0x022e, 0x0202, 0x0290, 0x0288, 0x029b, 0x028f, 0xfff2, 0x000e, 0x0290, 0x0288, 0x0290, 0x0290), 0x02: (['Lumberjack Area', 'Dark Lumberjack Area'], 0x02, 0x059c, 0x00d6, 0x04e6, 0x0138, 0x0558, 0x0143, 0x0563, 0xfffa, 0xfffa, 0x0138, 0x0550), - 0x0b: (['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], 0x03, 0x1600, 0x02ca, 0x060e, 0x0328, 0x0678, 0x0337, 0x0683, 0xfff6, 0xfff2, 0x035b, 0x0680), + 0x0b: (['West Death Mountain (Bottom)', 'West Dark Death Mountain (Top)'], 0x03, 0x1600, 0x02ca, 0x060e, 0x0328, 0x0678, 0x0337, 0x0683, 0xfff6, 0xfff2, 0x035b, 0x0680, 0x0118, 0x0860, 0x05c0, 0x00b8, 0x07ec, 0x0127, 0x086b, 0xfff8, 0x0004, 0x0148, 0x0850), 0x0e: (['East Death Mountain (Bottom)', 'East Dark Death Mountain (Bottom)'], 0x05, 0x1860, 0x031e, 0x0d00, 0x0388, 0x0da8, 0x038d, 0x0d7d, 0x0000, 0x0000, 0x0388, 0x0da8), 0x07: (['Death Mountain TR Pegs', 'Turtle Rock Area'], 0x07, 0x0804, 0x0102, 0x0e1a, 0x0160, 0x0e90, 0x016f, 0x0e97, 0xfffe, 0x0006, 0x0160, 0x0f20), 0x0a: (['Mountain Entry Area', 'Bumper Cave Area'], 0x0a, 0x0180, 0x0220, 0x0406, 0x0280, 0x0488, 0x028f, 0x0493, 0x0000, 0xfffa, 0x0280, 0x0488), diff --git a/Rom.py b/Rom.py index 484b990e..d6bf0452 100644 --- a/Rom.py +++ b/Rom.py @@ -629,21 +629,33 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): offset = 0x40 write_int16(rom, snes_to_pc(0x02E849 + (o * 2)), data[1] + offset) # owid - write_int16(rom, snes_to_pc(0x02E86B + (o * 2)), data[2]) #vram - write_int16(rom, snes_to_pc(0x02E88D + (o * 2)), data[3]) # BG scroll Y - write_int16(rom, snes_to_pc(0x02E8AF + (o * 2)), data[4]) # BG scroll X write_int16(rom, snes_to_pc(0x02E8D1 + (o * 2)), data[13] if offset > 0 and len(data) > 13 else data[5]) # link Y write_int16(rom, snes_to_pc(0x02E8F3 + (o * 2)), data[14] if offset > 0 and len(data) > 13 else data[6]) # link X - write_int16(rom, snes_to_pc(0x02E915 + (o * 2)), data[7]) # cam Y - write_int16(rom, snes_to_pc(0x02E937 + (o * 2)), data[8]) # cam X - write_int16(rom, snes_to_pc(0x02E959 + (o * 2)), data[9]) # unknown 1 - write_int16(rom, snes_to_pc(0x02E97B + (o * 2)), data[10]) # unknown 2 - - # flute menu blips - rom.write_byte(snes_to_pc(0x0AB783 + o), data[12] & 0xff) # X low byte - rom.write_byte(snes_to_pc(0x0AB78B + o), data[12] // 0x100) # X high byte - rom.write_byte(snes_to_pc(0x0AB793 + o), data[11] & 0xff) # Y low byte - rom.write_byte(snes_to_pc(0x0AB79B + o), data[11] // 0x100) # Y high byte + + if offset == 0 or len(data) <= 15: + write_int16(rom, snes_to_pc(0x02E86B + (o * 2)), data[2]) # vram + write_int16(rom, snes_to_pc(0x02E88D + (o * 2)), data[3]) # BG scroll Y + write_int16(rom, snes_to_pc(0x02E8AF + (o * 2)), data[4]) # BG scroll X + write_int16(rom, snes_to_pc(0x02E915 + (o * 2)), data[7]) # cam Y + write_int16(rom, snes_to_pc(0x02E937 + (o * 2)), data[8]) # cam X + write_int16(rom, snes_to_pc(0x02E959 + (o * 2)), data[9]) # unknown 1 + write_int16(rom, snes_to_pc(0x02E97B + (o * 2)), data[10]) # unknown 2 + rom.write_byte(snes_to_pc(0x0AB783 + o), data[12] & 0xff) # flute menu blip - X low byte + rom.write_byte(snes_to_pc(0x0AB78B + o), data[12] // 0x100) # flute menu blip - X high byte + rom.write_byte(snes_to_pc(0x0AB793 + o), data[11] & 0xff) # flute menu blip - Y low byte + rom.write_byte(snes_to_pc(0x0AB79B + o), data[11] // 0x100) # flute menu blip - Y high byte + else: # use alternate flute data + write_int16(rom, snes_to_pc(0x02E86B + (o * 2)), data[15]) # vram + write_int16(rom, snes_to_pc(0x02E88D + (o * 2)), data[16]) # BG scroll Y + write_int16(rom, snes_to_pc(0x02E8AF + (o * 2)), data[17]) # BG scroll X + write_int16(rom, snes_to_pc(0x02E915 + (o * 2)), data[18]) # cam Y + write_int16(rom, snes_to_pc(0x02E937 + (o * 2)), data[19]) # cam X + write_int16(rom, snes_to_pc(0x02E959 + (o * 2)), data[20]) # unknown 1 + write_int16(rom, snes_to_pc(0x02E97B + (o * 2)), data[21]) # unknown 2 + rom.write_byte(snes_to_pc(0x0AB783 + o), data[23] & 0xff) # flute menu blip - X low byte + rom.write_byte(snes_to_pc(0x0AB78B + o), data[23] // 0x100) # flute menu blip - X high byte + rom.write_byte(snes_to_pc(0x0AB793 + o), data[22] & 0xff) # flute menu blip - Y low byte + rom.write_byte(snes_to_pc(0x0AB79B + o), data[22] // 0x100) # flute menu blip - Y high byte # patch whirlpools if world.owWhirlpoolShuffle[player]: From 430953d3400082114b80979380c953feb4b0184b Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 12:24:44 -0600 Subject: [PATCH 26/73] Removed ladder from DDM --- OWEdges.py | 2 -- OverworldShuffle.py | 2 -- Regions.py | 4 ++-- Rom.py | 2 +- data/base2current.bps | Bin 87435 -> 87400 bytes 5 files changed, 3 insertions(+), 7 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index d4f5f8a1..ec4d8b05 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1590,9 +1590,7 @@ OWExitTypes = { 'Skull Woods Forgotten Bush (West)', 'Skull Woods Forgotten Bush (East)', 'GT Entry Approach', - 'Dark Death Mountain Ladder (North)', 'GT Entry Leave', - 'Dark Death Mountain Ladder (South)', 'Bumper Cave Entrance Rock', 'Skull Woods Pass Bush Row (West)', 'Skull Woods Pass Bush Row (East)', diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 7f18f8c1..b4368ae1 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1385,8 +1385,6 @@ ow_connections = { ], [ ('Spectacle Rock Leave', 'West Death Mountain (Top)'), ('Spectacle Rock Approach', 'Spectacle Rock Ledge'), - ('Dark Death Mountain Ladder (North)', 'West Dark Death Mountain (Bottom)'), - ('Dark Death Mountain Ladder (South)', 'West Dark Death Mountain (Top)'), ('West Dark Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain (Top)'), ('Bubble Boy Mirror Spot', 'West Dark Death Mountain (Bottom)'), ('West Dark Death Mountain (Bottom) Mirror Spot', 'West Dark Death Mountain (Bottom)'), diff --git a/Regions.py b/Regions.py index 47864ca1..dc4df9d9 100644 --- a/Regions.py +++ b/Regions.py @@ -129,9 +129,9 @@ def create_regions(world, player): create_dw_region(player, 'Skull Woods Forgotten Path (Southwest)', None, ['Skull Woods Forgotten Bush (West)', 'Lost Woods Southwest Mirror Spot', 'Skull Woods SW']), create_dw_region(player, 'Skull Woods Forgotten Path (Northeast)', None, ['Skull Woods Forgotten Bush (East)', 'Lost Woods East (Forgotten) Mirror Spot', 'Lost Woods West (Forgotten) Mirror Spot', 'Skull Woods EN']), create_dw_region(player, 'Dark Lumberjack Area', None, ['Dark World Lumberjack Shop', 'Lumberjack Mirror Spot', 'Dark Lumberjack WN', 'Dark Lumberjack SW']), - create_dw_region(player, 'West Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (West)', 'GT Entry Approach', 'Dark Death Mountain Ladder (North)', 'West Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain EN']), + create_dw_region(player, 'West Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (West)', 'GT Entry Approach', 'West Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain EN']), create_dw_region(player, 'GT Approach', None, ['GT Entry Leave', 'Ganons Tower']), - create_dw_region(player, 'West Dark Death Mountain (Bottom)', None, ['Dark Death Mountain Ladder (South)', 'Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'Spectacle Rock Mirror Spot', 'West Dark Death Mountain ES']), + create_dw_region(player, 'West Dark Death Mountain (Bottom)', None, ['Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'Spectacle Rock Mirror Spot', 'West Dark Death Mountain ES']), create_dw_region(player, 'East Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Superbunny Cave (Top)', 'Hookshot Cave', 'East Death Mountain (Top West) Mirror Spot', 'East Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain WN', 'East Dark Death Mountain EN']), create_dw_region(player, 'East Dark Death Mountain (Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Teleporter (East)', 'Fairy Ascension Mirror Spot']), create_dw_region(player, 'East Dark Death Mountain (Bottom Left)', None, ['Death Mountain Bridge Mirror Spot', 'East Dark Death Mountain WS']), diff --git a/Rom.py b/Rom.py index d6bf0452..6b73d46f 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '2fe9f5776fa383e419e6feb779e583b5' +RANDOMIZERBASEHASH = 'd2aecda46578746112f5349645924c53' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 0c5a26337ffe2b7220ebcf7428810a2012d8952b..e95eded1906f1eea7f2c240c5e9039910514c7e2 100644 GIT binary patch delta 2709 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 QK_ma2DI7dJF>n9>01A)@LjV8( From 44c63e2004382769119c14d87a05627ddde6e7aa Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 12:41:39 -0600 Subject: [PATCH 27/73] Some Inverted terrain changes for EDM --- Rom.py | 2 +- data/base2current.bps | Bin 87400 -> 87381 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index 6b73d46f..cf4167d1 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'd2aecda46578746112f5349645924c53' +RANDOMIZERBASEHASH = 'c5ca2300535898aeb44355d9ce3689aa' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index e95eded1906f1eea7f2c240c5e9039910514c7e2..ea1d4e68d8a1aefc963c451d96d870bc9bc3e556 100644 GIT binary patch delta 3078 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 delta 3130 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 From 0bc72f77cf0f4e12764be761131865653b7df168 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 13:30:02 -0600 Subject: [PATCH 28/73] Restored vanilla ladder at Dark Graveyard in Inverted --- Rom.py | 2 +- data/base2current.bps | Bin 87381 -> 87358 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index cf4167d1..36a14b16 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'c5ca2300535898aeb44355d9ce3689aa' +RANDOMIZERBASEHASH = '6ae34ddfb50b2e113bcd688715d2e689' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index ea1d4e68d8a1aefc963c451d96d870bc9bc3e556..38eaed92166f79bbc4792a7021621dfe2faed11d 100644 GIT binary patch delta 2615 zcmW+%Yg7~07M?RnOn8TfNJV5afWSo_idw}~P(<-fsaoYKQlB6S_EN2nMVN^O8*mch zE{-;8uuQ;!7`U@66)R6$2vmt$P{4|Uy;7+)7J3!>@W%UNf9I^d_d4r*dwu6ST@|AG z3QuIe-N%I#sNG-?g`@f4j_*T3pu}U46I{pr&@Sl1 z*P;y&B?v%euvV}i)j_*ph1-cX?iUrA{$>FsRI15Y5GZ_&^1x4ILQD8o(I*Ih(hBd1 zyWBSRaf^@Bd-O>-O=#6|Ad?u88d@dGP%^kXTz3>6Q{Vf%gx&t$QMm6AgmU3;hgbM$ z7rb)xM^j;v(^SXAZthvyQHFea3u2viqmxkK^gil`Kb@AMC|K;gRdV_cx2cdJFT!PK zZ~r2TUh(nqwKPKxb(aX0j0wk{*%&fh$2r?`8)49Snw^28%WeA%9=J?Ho*-~tiV9$b z>v|LdU%JjhA^bhpdkFudov)T2K|V2^+{)G#LdlTYPOgL@^E z)sd(9LXQ*3%RZB|ixV~jWMn&25ZnN@hEMl84Ic9;!yS(u+3qQ6i#|MAX z30c%ueEdFthnj;>CGVh&3_>J7ulzakrrSBAuPxY+jF`cKb6IqhYUTK*5?*eaE<#es zxO~BN_BD>gs0K2O;mDy5@G&1pNBI)-41_kpo$A?kkx6QlsGcvZ8JvKRH1YesE)@s1 zq*A(V6-;d@U#eoRww_>JD7EQoEs&J1`s%id`i??f2tT*+nzQpcH=KzGOEah3op}_z zZhm6dr~2kbd@}`4Zf-$~VDT+w*g}rpI;_;$JO3R9aTm1$t!f?)IR)3};Y?Dbsnm%{ zj%02{GFEVfm$y=UCl)dS%qnk~M;Y=vs^KJinmtiDIaS#y{I{XR+-z`fVot$VC5kA+?II^UT<*w+a>hP z3+<9tMT0xLIv7^m9>I5IL)@LOJ`^t0o~ca#62l5I*)0nnUWG=kvXN_V zVfEdBI5ObrIibzdXz|H#Xep&7+A4i)&T#pHoZ*wf2X%YtRb`fj@+M9iX0cg?|8b`h zEHAAhg1ltInicZC~n5H9e`-6dWZn%kwL=a+m^x1X{m<+ZmD{deY&I$ws++tFBt9$Lmr{T-Q{Il*bgd)KE{wSV36`Xtgy|$8h@o~)R6_QdCNLJn~F=JGSRX{{q z4pS(k{J;*4Rw<$~iAeaXC&DvwtEPoFS^}*TQZBx2(QlBzf?nSVev38i!Fbrx84NC16?KKU@rLZ1B9I zQ;{pGdR7{M>YL-CaMu~9jVgSy-%ZL3b%T7n(%brui@lZ?(Wwv%>mLM(VPzEcKGg^G zgV}ahuYHgjldwljb#1z76BVwgG>Ok8xe=+i$fu)IiSxG%^62M=g{%5?3YElkt3E5t z2J(;l%G{$`=+~vmlVHt{6VVLV@gqHHUFXGPQN&U^&dBU7@W~*siV}?Y5dQjcw&T)H zpB)3LflOi@$R8%6Do{Pl3-Z3pRZT}0iOtVEAU$!*gg&C;{jB7G#`PF;C@HcnO*C$qjb(G0eT-8sdbYKk*T?KZs3 z;%ZB`jIcfVfUkT_y=NWdNjrEtq&jFMqN<-crUsHQwMUJK{9@PR4a(Je`druu$zlb63muq4zOFc=jm5YiE4cr97s@~!H_lBykMkK z&h{sysu?$vDA4e^*36XoS|iw;lhF416rOqz(#E{-{n7k^vENa|i#D#8b!n(^T3*pm zZGRXBJB(*jhl14VloHH*p2o_*I&(NpRl;b5Y#M*&k9-LVV+kP&dMC`nji+Z?%(j=7 zK-=?i!<4x%)afyq?4H_GA?g!2Pn)IDB~pH&ZY-8nn;=2IyEr-d>O`Lw=eX*QOsGxp cM#ZioC)bJ>S+)IvC@V_Rc*wKfSsv8?Kk@LB{Qv*} delta 2673 zcmWkvYg7~07M?RnAcRK($U_hrMidZ%AoxP6s2~W~(u!7*q9R2wih6z98fQ|2226&y zg%ML4lmQGDqc?4>B8G=u5PT4|U;*m`uGQ+b#)=hfuiW_Kd}puy?Q_=JdwqNFOAUga z20>Yf$FawB%VV00r_|Z0)bXR0*?rnsN&e$oIEg}8dy%hEldpR1td^`-b5Dd9=sVg< z4Qhf=6u=L*4Txb8ib5w~H(G$^Kr;$-{CI#1Em4KT5Q;#bf;+w$%>xA;ww~S1_bj*kPZR_29#^+5Nty@)(Iat z_K3F+aES-#gSrfyCKy#V1PNH|#aI<2ngN0naTN)j^uu zGL#4>++tCp>9*T#g!^1EosoQje3x}|=^gEaLQS6P=Bm}?iEb|2{!<(*@JJ9^dO6`& zTJk$nsmCES#$J=vCy$fQYB(8j*CI=}R8Ib73Lg^@iuRjU#2a{?`fD6x)fQPD$-8Vx z`6l}vVDd^>FBq3`g)<=a@3;|YsZBtBc8!y9E;D6>?-4TDq)WPhP=aY$vR>#~eU+m` zEmu6H*q9JnaOZ9NAjo<{uYpw_Uiey4gFV2wTY$~Eln;#N-+)v3i>6Z zV2YI%jM=Z{f(=6$yGfy1ZOpnQSHQcg+fWv4y|x1PqT%|rRcH@HURSv9=IGp~3auDd z|2rIZon&T1>-Di{Aq-s4@?Tu4=3&-&^DIhVeB}%rW{MOb@^Ud=Lk8m)bZ>NIpx+y7@|Q* z`!Ru6T46t;drqh@mLzP_671O!(iqgr{`?!aLgmE1$wer%pUo`p- z%ZZgR+4^C~+7xva`Sm5v&TfL)N}AM1exz33FEa*tYINS78aiL^KtmGft+BbDX3pka z!fyHC@AF{^m{nld5Jrg%tHLM&>zyg0==p6)w9?qcuAE7g^U_C~2Z@TEh_bXvPf%E` zUziJ)nre%)Ak3D_?prUU&W|>m#qV6hMxQeaJLG0})*%$8-FS%yZidM>e^?$rkEuLW za00_hWEEqT=Z!5~M+^5`3-_p%`(G>fgMWp}ThFl@=iU8YMmV(Rb>>+}aT{lKhK+PN zCfVF2dDGy}7|e=jmuMV}yR;R1F=$E_E%dT`(-SIvFE|<#Ftn5Y`ufWRTn!@0LBS?58yQd&UlA z6KMOU;1T&??(=d_v+SWzXnkb9hEWJ88IcAL`yyl4tKzGR9hdJ&^gFB+B?=$0mGSZN|8_e;la%Gc0wtU_BLBiH<>Bl9)dz?6Pt zh;Ad4_4`kol%Z+$XbUnn49g3JSQ*bSI?6P#(KE^b`=G3GOj}Sb7B-4)veWf{z^u)T zk}0a$2KW1C_%(H=uxY^>HaJ4V1}yo#%GEggeLAz*5&?dZ`Ds-2^jvqDQ#}XIh52QusN`W@Zqnt&zA0!`=!KMJ4Va;OMD9ntf3ksw!&|} zP7|%|_WgWNIVdBxz{I;L$O1)o_o1oq$6a5Sv>T^!;{K8d8!x>QJnrS-p;7R!dkhhL z!|->Txmj zBp6k(wIAzesHkW;;?Zbw!76FjEkgLfZGk z;h~FRCAT@7Lzm=r3Ds$!)ImXQQdSTnq~0`$M1@#|+G9ahHGvHh<_g&PpBkV1sH^8* zJ#SH&$uF)%dpJ_(c1Rp4b}>Xh9E(qlg!G3Ic)(cG7Z0r{CK#2KKd&B#8E=8ph4MJd zD0XHp8xhvu*AkDNaX0^SZ)$&&etC=h?c>Ltoz#;iGnNPPN0H%smzL3??2hFWNN|Q; z(V?IV?5EJAI4s_92v&Tm)$Yyu_7@!b?ZUhLXs={e;y-l3&RxZRSua8e)#M^m-s5DE zlV{RFm6(+1=9<3yb1f41EIX)M1LKAp{bqWKsAGPSN9h$6Yf0sC%$i|*YYVZZvMWqO z!whe(eeV%(f&Hx9AjE7k;{^Ng_B{G}NwP{;2Xm5Cl^C*y80Wk^70=#t%~7ev20^g? z2xC;&`CB8|aDcNT6~5lPsaCE--Ym5dR+g#jke^!pZj_CPHLZH{3Pn0wxPI2veAYR& z!F Date: Sat, 15 Jan 2022 14:25:32 -0600 Subject: [PATCH 29/73] Logic and region changes for EDM Spiral Mimic Bridge in Inverted --- OWEdges.py | 6 ++++++ OverworldShuffle.py | 5 +++++ Regions.py | 5 +++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index ec4d8b05..7f7e5afb 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -703,6 +703,7 @@ OWTileRegions = bidict({ 'East Death Mountain (Top East)': 0x05, 'Spiral Cave Ledge': 0x05, 'Mimic Cave Ledge': 0x05, + 'Spiral Mimic Ledge Extend': 0x05, 'Fairy Ascension Ledge': 0x05, 'Fairy Ascension Plateau': 0x05, 'East Death Mountain (Bottom Left)': 0x05, @@ -1402,6 +1403,7 @@ OWExitTypes = { 'East Death Mountain Mimic Ledge Drop', 'Spiral Ledge Drop', 'Mimic Ledge Drop', + 'Spiral Mimic Ledge Drop', 'Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau Ledge Drop', 'TR Pegs Ledge Drop', @@ -1514,6 +1516,10 @@ OWExitTypes = { 'Fairy Ascension Rocks (North)', 'DM Broken Bridge (West)', 'DM Broken Bridge (East)', + 'Spiral Mimic Bridge (West)', + 'Spiral Mimic Bridge (East)', + 'Spiral Ledge Approach', + 'Mimic Ledge Approach', 'Fairy Ascension Rocks (South)', 'Floating Island Bridge (West)', 'TR Pegs Ledge Entry', diff --git a/OverworldShuffle.py b/OverworldShuffle.py index b4368ae1..0c019feb 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1405,6 +1405,11 @@ ow_connections = { ('Floating Island Bridge (East)', 'Death Mountain Floating Island'), ('East Death Mountain Mimic Ledge Drop', 'Mimic Cave Ledge'), ('Mimic Ledge Drop', 'East Death Mountain (Bottom)'), + ('Spiral Mimic Bridge (West)', 'Spiral Mimic Ledge Extend'), + ('Spiral Mimic Bridge (East)', 'Spiral Mimic Ledge Extend'), + ('Spiral Ledge Approach', 'Spiral Cave Ledge'), + ('Mimic Ledge Approach', 'Mimic Cave Ledge'), + ('Spiral Mimic Ledge Drop', 'Fairy Ascension Ledge'), ('East Dark Death Mountain (Top West) Mirror Spot', 'East Dark Death Mountain (Top)'), ('East Dark Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain (Top)'), ('TR Ledge (West) Mirror Spot', 'Dark Death Mountain Ledge'), diff --git a/Regions.py b/Regions.py index dc4df9d9..2cf2783e 100644 --- a/Regions.py +++ b/Regions.py @@ -17,8 +17,9 @@ def create_regions(world, player): 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, '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 Cave', 'TR Ledge (West) Mirror Spot']), - create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Ledge Drop', 'Mimic Cave', 'TR Ledge (East) Mirror Spot']), + create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Ledge Drop', 'Spiral Mimic Bridge (West)', 'Spiral Cave', 'TR Ledge (West) Mirror Spot']), + create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Ledge Drop', 'Spiral Mimic Bridge (East)', 'Mimic Cave', 'TR Ledge (East) Mirror Spot']), + create_lw_region(player, 'Spiral Mimic Ledge Extend', None, ['Spiral Ledge Approach', 'Mimic Ledge Approach', 'Spiral Mimic Ledge Drop']), create_lw_region(player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)', 'TR Isolated Mirror Spot']), create_lw_region(player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Rocks (North)', 'Fairy Ascension Plateau Ledge Drop', 'Fairy Ascension Cave (Bottom)', 'East Dark Death Mountain (Bottom Plateau) Mirror Spot']), create_lw_region(player, 'East Death Mountain (Bottom Left)', None, ['DM Broken Bridge (West)', 'East Dark Death Mountain (Bottom Left) Mirror Spot', 'East Death Mountain WS']), From f6d309ca76467add4f6721f1ec74726d6e93ea8b Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 14:31:23 -0600 Subject: [PATCH 30/73] Logic rules for Inverted TR Peg Puzzle --- OverworldGlitchRules.py | 1 + Rules.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/OverworldGlitchRules.py b/OverworldGlitchRules.py index 40c1efb9..cfe15841 100644 --- a/OverworldGlitchRules.py +++ b/OverworldGlitchRules.py @@ -150,6 +150,7 @@ def get_boots_clip_exits_lw(inverted = False): yield ('WDM DMD To River Bend Clip', 'East Death Mountain (Bottom Left)', 'River Bend Area') yield ('EDM DMD To River Bend Clip', 'East Death Mountain (Bottom)', 'River Bend Area') yield ('TR Pegs Ledge Clip', 'Death Mountain TR Pegs', 'Death Mountain TR Pegs Ledge') + yield ('TR Pegs Ledge Descent Clip', 'Death Mountain TR Pegs Ledge', 'Death Mountain TR Pegs') yield ('TR Pegs To EDM Clip', 'Death Mountain TR Pegs', 'East Death Mountain (Top East)') yield ('Zora DMD Clip', 'Death Mountain TR Pegs', 'Zora Waterfall Area') yield ('Mountain Entry To Ledge Clip', 'Mountain Entry Area', 'Mountain Entry Ledge') diff --git a/Rules.py b/Rules.py index c509b55b..ceabdf72 100644 --- a/Rules.py +++ b/Rules.py @@ -916,7 +916,9 @@ def ow_rules(world, player): else: set_rule(world.get_entrance('Turtle Rock Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Turtle Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) + set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) + set_rule(world.get_entrance('TR Pegs Ledge Drop', player), lambda state: False) + set_rule(world.get_entrance('TR Pegs Ledge Leave', player), lambda state: state.has('Hammer', player) and state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) if not world.is_tile_swapped(0x0a, player): set_rule(world.get_entrance('Mountain Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) From c2f6799885cc880f883ddab9abe27fb7d6ad845e Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 17:37:16 -0600 Subject: [PATCH 31/73] Only start at Big Bomb Shop if not ER --- BaseClasses.py | 3 +++ DoorShuffle.py | 6 +++--- EntranceShuffle.py | 26 +++++++++++++------------- OverworldShuffle.py | 4 ++-- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index d43c8751..7e17d469 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -304,6 +304,9 @@ class World(object): def is_tile_swapped(self, owid, player): return (self.mode[player] == 'inverted') != (owid in self.owswaps[player][0] and self.owMixed[player]) + def is_bombshop_start(self, player): + return self.is_tile_swapped(0x2c, player) and (self.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not self.shufflelinks[player]) + def check_for_door(self, doorname, player): if isinstance(doorname, Door): return doorname diff --git a/DoorShuffle.py b/DoorShuffle.py index 17fda12c..45ecbc7b 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1815,7 +1815,7 @@ def remove_pair_type_if_present(door, world, player): def find_inaccessible_regions(world, player): world.inaccessible_regions[player] = [] - start_regions = ['Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint'] + start_regions = ['Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint'] regs = convert_regions(start_regions, world, player) all_regions = [r for r in world.regions if r.player == player and r.type is not RegionType.Dungeon] visited_regions = set() @@ -1851,7 +1851,7 @@ def find_accessible_entrances(world, player, builder): if world.mode[player] == 'standard' and builder.name == 'Hyrule Castle': start_regions = ['Hyrule Castle Courtyard'] else: - start_regions = ['Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint'] + start_regions = ['Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint'] if world.is_tile_swapped(0x1b, player): start_regions.append('Hyrule Castle Ledge') regs = convert_regions(start_regions, world, player) @@ -1886,7 +1886,7 @@ def find_accessible_entrances(world, player, builder): def valid_inaccessible_region(world, r, player): - return r.type is not RegionType.Cave or (len(r.exits) > 0 and r.name not in ['Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop', 'Chris Houlihan Room']) + return r.type is not RegionType.Cave or (len(r.exits) > 0 and r.name not in ['Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop', 'Chris Houlihan Room']) def add_inaccessible_doors(world, player): diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 826dc585..90f78451 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -54,7 +54,7 @@ def link_entrances(world, player): for exitname, regionname in mandatory_connections: connect_simple(world, exitname, regionname, player) - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): connect_simple(world, 'Links House S&Q', 'Links House', player) else: connect_simple(world, 'Links House S&Q', 'Big Bomb Shop', player) @@ -78,7 +78,7 @@ def link_entrances(world, player): connect_logical(world, entrancename, exitname, player, True) if invFlag: world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance('Dark Sanctuary Hint', player).parent_region) - if world.is_tile_swapped(0x2c, player): + if world.is_bombshop_start(player): world.get_entrance('Big Bomb Shop Exit', player).connect(world.get_entrance('Big Bomb Shop', player).parent_region) ignore_pool = False @@ -215,7 +215,7 @@ def link_entrances(world, player): junk_fill_inaccessible(world, player) # place bomb shop, has limited options - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] @@ -261,7 +261,7 @@ def link_entrances(world, player): place_old_man(world, lw_entrances if not invFlag else dw_entrances, player) # place bomb shop, has limited options - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] @@ -319,7 +319,7 @@ def link_entrances(world, player): place_old_man(world, lw_entrances if not invFlag else dw_entrances, player, list(zip(*drop_connections + dropexit_connections))[0]) # place bomb shop, has limited options - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): bomb_shop_doors = [e for e in entrance_pool if e not in list(zip(*drop_connections + dropexit_connections))[0]] if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in bomb_shop_doors if e not in ['Pyramid Fairy']] @@ -422,7 +422,7 @@ def link_entrances(world, player): connect_caves(world, lw_entrances, dw_entrances, caves, player) # place bomb shop, has limited options - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] @@ -477,7 +477,7 @@ def link_entrances(world, player): connect_caves(world, connector_entrances, [], caves, player) # place bomb shop, has limited options - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] @@ -527,7 +527,7 @@ def link_entrances(world, player): place_old_man(world, pool, player) # place bomb shop, has limited options - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] @@ -611,7 +611,7 @@ def link_entrances(world, player): caves.append('Old Man Cave Exit (West)') # place bomb shop, has limited options - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] @@ -642,8 +642,8 @@ def link_entrances(world, player): # ensure Houlihan exits where Links House does # TODO: Plando should overrule this if not links_house: - for links_house in world.get_entrance('Links House Exit' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop Exit', player).connected_region.exits: - if links_house.connected_region and links_house.connected_region.name == ('Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop'): + for links_house in world.get_entrance('Links House Exit' if not world.is_bombshop_start(player) else 'Big Bomb Shop Exit', player).connected_region.exits: + if links_house.connected_region and links_house.connected_region.name == ('Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop'): links_house = links_house.name break connect_exit(world, 'Chris Houlihan Room Exit', links_house, player) @@ -1342,7 +1342,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player): def place_links_house(world, player, ignore_list=[]): invFlag = world.mode[player] == 'inverted' if world.mode[player] == 'standard' or not world.shufflelinks[player]: - links_house = 'Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop' + links_house = 'Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop' else: if invFlag: for dark_sanc in world.get_entrance('Dark Sanctuary Hint Exit', player).connected_region.exits: @@ -1361,7 +1361,7 @@ def place_links_house(world, player, ignore_list=[]): links_house_doors = [e for e in links_house_doors if e not in ignore_list] assert len(links_house_doors), 'No valid candidates to place Links House' links_house = random.choice(links_house_doors) - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): connect_two_way(world, links_house, 'Links House Exit', player) else: connect_entrance(world, links_house, 'Big Bomb Shop', player) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 0c019feb..40c98c36 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -841,7 +841,7 @@ def can_reach_smith(world, player): found = False explored_regions = list() - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): start_region = 'Links House' else: start_region = 'Big Bomb Shop' @@ -1031,7 +1031,7 @@ def validate_layout(world, player): explored_regions = list() if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not world.shufflelinks[player]: - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): start_region = 'Links House Area' else: start_region = 'Big Bomb Shop Area' From 5dc8f59f7341ff114382c906071a50af7d654ecb Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 17:57:46 -0600 Subject: [PATCH 32/73] Links House tile can now be Tile Swapped --- OWEdges.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index 7f7e5afb..6905570f 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1184,14 +1184,14 @@ OWTileGroups = { 0x6b ] ), - # ("Links", "Regular", "None"): ( - # [ - # 0x2c - # ], - # [ - # 0x6c - # ] - # ), + ("Links", "Regular", "None"): ( + [ + 0x2c + ], + [ + 0x6c + ] + ), ("Tree Line", "Regular", "None"): ( [ 0x2e From 593ce8086adb7d19381fd580a9c510e06715f05f Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 18:00:33 -0600 Subject: [PATCH 33/73] Only start at Big Bomb Shop if not ER --- Rom.py | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/Rom.py b/Rom.py index 36a14b16..edb46102 100644 --- a/Rom.py +++ b/Rom.py @@ -812,7 +812,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): if should_be_bunny(sanc_region, world.mode[player]): rom.write_bytes(0x13fff2, [0x12, 0x00]) - if not world.is_tile_swapped(0x2c, player): + if not world.is_bombshop_start(player): lh_name = 'Links House' else: lh_name = 'Big Bomb Shop' @@ -2207,14 +2207,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 world.is_tile_swapped(0x2c, player): - entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) - if world.shufflelinks[player]: - entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) - else: + if not world.is_bombshop_start(player): entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) - if world.shufflelinks[player]: - entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) + else: + entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) 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) @@ -2649,24 +2645,25 @@ def set_inverted_mode(world, player, rom, inverted_buffer): if world.is_tile_swapped(0x29, player): rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact if world.is_tile_swapped(0x2c, player): - rom.write_bytes(snes_to_pc(0x03F484), [0xFD, 0x4B, 0x68]) # place bed in bomb shop - - # spawn in bomb shop - patch_shuffled_bomb_shop(world, rom, player) - rom.write_byte(snes_to_pc(0x02D8D2), 0x1C) - rom.write_bytes(snes_to_pc(0x02D8E0), [0x23, 0x22, 0x23, 0x23, 0x18, 0x18, 0x18, 0x19]) - rom.write_byte(snes_to_pc(0x02D919), 0x18) - rom.write_byte(snes_to_pc(0x02D927), 0x23) - write_int16(rom, snes_to_pc(0x02D934), 0x2398) - rom.write_byte(snes_to_pc(0x02D943), 0x18) - write_int16(rom, snes_to_pc(0x02D950), 0x0087) - write_int16(rom, snes_to_pc(0x02D95E), 0x0081) - rom.write_byte(snes_to_pc(0x02D9A4), 0x53) + if world.is_bombshop_start(player): + rom.write_bytes(snes_to_pc(0x03F484), [0xFD, 0x4B, 0x68]) # place bed in bomb shop + + # spawn in bomb shop + patch_shuffled_bomb_shop(world, rom, player) + rom.write_byte(snes_to_pc(0x02D8D2), 0x1C) + rom.write_bytes(snes_to_pc(0x02D8E0), [0x23, 0x22, 0x23, 0x23, 0x18, 0x18, 0x18, 0x19]) + rom.write_byte(snes_to_pc(0x02D919), 0x18) + rom.write_byte(snes_to_pc(0x02D927), 0x23) + write_int16(rom, snes_to_pc(0x02D934), 0x2398) + rom.write_byte(snes_to_pc(0x02D943), 0x18) + write_int16(rom, snes_to_pc(0x02D950), 0x0087) + write_int16(rom, snes_to_pc(0x02D95E), 0x0081) + rom.write_byte(snes_to_pc(0x02D9A4), 0x53) - # disable custom exit on links house exit - rom.write_byte(snes_to_pc(0x02E225), 0x1C) - rom.write_byte(snes_to_pc(0x02DAEE), 0x1C) - rom.write_byte(snes_to_pc(0x02DB8C), 0x6C) + # disable custom exit on links house exit + rom.write_byte(snes_to_pc(0x02E225), 0x1C) + rom.write_byte(snes_to_pc(0x02DAEE), 0x1C) + rom.write_byte(snes_to_pc(0x02DB8C), 0x6C) if world.is_tile_swapped(0x2f, player): rom.write_bytes(snes_to_pc(0x1BC80D), [0xB2, 0x0B, 0x82]) # add warp under rock rom.write_byte(snes_to_pc(0x1BC590), 0x00) # remove secret portal From 4f730844f693f6d08b1fe88705f94b4f9561f5f8 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 15 Jan 2022 20:56:56 -0600 Subject: [PATCH 34/73] Made flute SFX louder for preactivated flute item get --- Rom.py | 2 +- data/base2current.bps | Bin 87358 -> 87358 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index edb46102..7ec76058 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '6ae34ddfb50b2e113bcd688715d2e689' +RANDOMIZERBASEHASH = 'c3d7e407be9e5390292dec544dfbde9e' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 38eaed92166f79bbc4792a7021621dfe2faed11d..43708bf9a61242e20bea154c54ac7b4aeccaf6c0 100644 GIT binary patch delta 35 tcmV+;0Nnq+ss+BP1+YZ{1RVL}2D3>4u5keqv-om8;t149Mc7HPJ5~&(4-EhS delta 35 tcmV+;0Nnq+ss+BP1+YZ{1jhI|2eU~5u5kfAv-om8;t0Tb6TS>QCEpE*4#@xj From 36a6f210217a661607106b50b1052c46bb134469 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Tue, 18 Jan 2022 03:14:40 -0600 Subject: [PATCH 35/73] Fixed issue with Inverted Mirror Bonks not getting applied appropriately --- Rom.py | 2 +- data/base2current.bps | Bin 87358 -> 87368 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index 7ec76058..c38b495c 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'c3d7e407be9e5390292dec544dfbde9e' +RANDOMIZERBASEHASH = 'fbdd4f1bf5722a38ce147b4584d6ccb8' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 43708bf9a61242e20bea154c54ac7b4aeccaf6c0..581c770e3f40a0898dd2049e31e06ee5192f3aa2 100644 GIT binary patch delta 2796 zcmWkv3se(F7v2d8ghwEt@|3bHK0qEuMNvS6DuRkF71ZjF78MbUf-Tmnt#LLr)PS2M zPGQA}L0O~;r2)5=f?{~+55WgP3l^|S@wZy7HLbLYdgNcvocrDH%)K*b?%aE4E*eE$ zMp4OhkD`ZU>qC-_g;d6JcX_rzwpeHbslILmioUdmtPnA$P$pFbgRK(ZCC}2>d|- z8WN;~EF`lF0%uXW-KXHcsM~IZ+p#Y84;7I!9tVX=H4%@d2={>sbW*4Q#mHY|0IRr8 z(QW{2DAu9hZR-%b%F{v^oU^imO2>>J%>n8qnIMTN8h=42Ar_y6d!+; zPEy3f{z{>eG6=9oHi`(>vM&7GR&>v08h>mjNiQGxZOJqcfb3k8Kp9%$x&}m|)2@*q zlDp-43kV#paP`v9f%noLHl?!zS5kzohpnWDqdjZ}ztaq~*dt!t)X$2))DkRL>~RE4 zm0uv%-HW9J%8Y^dA=F4&KuZbv5m)Hz|j9ZhW7fVX6ve1d>;ZaDqa)Q)? ziC_n}CoA2~>zReEyCm!hgfg4XEwZq|;$ZV5MBV7uZJq*AH#fGez?)COPPj#2Kfv99 z^8je%9F;Stf(ULw%@g2Bb+grew(0s+fVx*ykw?l@DK9g=^Ulmo_LaUQx@0#?Yh@ zSu2D^%i@hi)+i=;EzB*vU&CG|>ix|R-s+M`=HGdZ*GtTgxw#je-|m`VUVG5zsLD3+ zv^(8kfmprB$@n_oP}?pm`+Navljj@Xj$OQ5;3fE5X3y6(Cse+53`GX&3h4@UeBGMb zGAiE~WinkR)41z(`KEm1EbjYr`Ns3-^hZkn=1J#SS^`x$KQOne6B_f4#k}M;nnjR2 z+OZL8r{x>V8%%eT3e08^5Xc%?M-rymihC@w@@2=vmTs<#Xm)qMSGaLe^ zaVO#ni{D#T$z*s#N(D|6RfoybNXhi6Mr0^v4r~Z8EqWl-5 zi-e~#Iu+2h9XHHED$WcVlqikLlVPLO=JJ&{zIx|x{yu+%Q) zY0C&+_8EYdcG+o&Rr`jxV9S@=qAdWkZDtN`7sIBfEoQejl92JI^wLg+*`3Kok-ekf zAPTwB_~GOPy1X{$G=>$)%Y0N#`c}5FmF;h3Z?&;c+Snib%G92EmRXr_=bRk>w>_&X z%R-E|u~uialPtxgySk-gMnBq+-BJB-h}33>pS{HFo8Qojn^Dxwp!n#Z2Ngowglda- zu46|PDW>amYYQINtSNYWboyTHPIBcLi87KW&-JQ)?!5)Y{L zvPw+h`f0N@WH>WdQc}HmRAF^Ag^wztnG6&%;15=yq=8u1*tsQ_SMcj;9*A0`9S9Rh zvXOaUl6#D0KLo)wuGtz|DS~o52HhWsh)mk7>ENm@Q>^yuzrlGI-7Yb$6%sW+RqC~r zn`!4WIuDY|XeG65RFR{byF|lCm!PCUna}Zw$uYIEeorXO{JY>hS`dC)Xnw-S{M z`pvaZ)wFrE2bzqdid->PVrLj1r;UtzR0+zAEvcK>9$1ZqjAQw{x#mygvx`>Ic~$9X zcrePhwkw$louXlc;Tq<^s^2RlrkJcJ23{m@qqVarR%jc6^3yFJZ5O9nrH57748U#D)^;Q;$GuGvKV z8)tB+NOi-vUnd@nzJnXD>tp9U(XZUmsx4B94c9N`h1yWEwB?Mutb=?}wcV@Ya(6r? zc-wn6S5q96SwuE_W*K_#7t(7}&o_r;cp8thCBhmf7shJi=$Xyd%AI7{HPV8`9ou3E6*(wb^$|pBKR{ z1Ec~2+hxqw*nm|=1UDC=&;D2CwRGmy#($o+s?EgbSKK`uVB;F8 z17yO{touF!j|h}T(QNr<>xQ)y6V+!_mnXejpJwzo5ML?1gP?r=mq>!>tT` zrc+Uy`DUDvL~&s_h+gq zDUFax=9I4r#UP4t6oRQfQ5N=Pj@)9h{biYAd-75rIsd6TCtA*=HzoKvefyDT9O=H&-kS7yYtgpE?cD7mee;&B(GXMYp delta 2739 zcmWkv3se)=7M(juAbbJ|pdg401M+!*!~%YhCnzHLX{GqZM|rgPfksiE)ru~|Ol;7g zlaIGB+K2&}fC)_p-z-bjO8Dr);D?}vDp*lytJPX#rBBf=dE>fkpL5ndXWezqx##YC z#VTsEiuBQb%131TBa%rYsDhLeO?bs#2T37iuZ|&H(Q<;7t_sSbUyr zHyqaj6N~|&!l~nBkqMHaA_ z>lS?mz|SzveZV(=h*@-y++xf{Nld57fZ<{@(70VA@U6#7bgUn~^b7;j zV4&ADkDLMKanS(^e+cJ$DZo)^_4*JD!@s?j!cW6*yeEh09Y*Dj zgR4jie>6}hR8bZbdF-O_1OwyE@8!c$?t*UFyt0=m;7^(cGyO8ewgESp@zEt}{BPq0H%ychXhW+jtGQNg1Dt zrY2uyEP(nAWg#hdiSPy283p4#M}Y->iN|rqtn&awa%-|pV#ycR7{U|p;-wHrIW%`? z04U;iZ&)P=eCS|omxR6HgxqEHO|CrSaCe2^;|};>^JH|~!HsX;8N^?~R-zbveVe;U z%mSd9^H3#D2RJvk=_!~@_AurUSF|Y)P@`3~Wu#oa{B=Pcmu86<0Vyo~re2bAfx!{N zj>l09{s;!Lhrj`@j-3fW0le9g!q1iXj0&`IhtG_+Soz=^ve+`xx0-mwUzaXTE9 zDF19;UCjr}krS8YEnZv1E|FsJ!A8qLM&sr2jP-<`rZ#YDrf-1US zJtBt@NyM2jHuHrN+tk*HHM&)OmF|63-RKUZl8O3)ZYANNIqc7Xwuyaa4;Yv?}T-cdKs@WboVh&L)SUw89`@&_T7wx`p zC9xCFbc?%{b{YKvoZmOblS9(Y*0sU~y5r3yrx2t{LH~Qfy>qagX>MnF+L@~z%!3Z* z+vpRT$tH$Ac~*fv?%Z%?g9Crj!8pC(Re1Ceigh+)`pzd!^LIWu8okG`m3+U^VQ=bSq;U?HQ~0Zl z$Z|Y)iZJdHk?i=BHyWY&)@)nh9|-^y z3@n`#Fr%MLg(~yM4M-C3L_HA{?stcu4CDb%cy=HPEaC1B!~-w`dfXmEw@rf+x5JWs z-qVr^bf`pc&Ky%ZJ=laXWh%W$qJLly>jFeJ{!b0Usz`Y(>cVV3z_HIc#h3*1?xgud zrsyv(8&d}Bc!8VXi97KzyEbYc97LP}G3)Ch@#gDwEJDOM1z4hEF9Bkjc5l?`R3buw zB|_Jo8GebMXuCMGBhu-%{`9*LBTwyvQ{6%rY3V(gFmF&kW%ed5nM$h+B?|oG?~I>r z)EdHa2H9w13N#Leq?E1DcKCIMv(_))!Xtqk3WJpnJelJy{6T;gY*iZp-Dwhr|%vb@$8M ztS#J^whNA{b7SrEwii@GIhA;+?LIa4uM6;z5L);a`R3!nd# z;+fqWv~ff|qQF)|`Mn%qgXQ-srcb`b*y4dh?2@s;D!Eh4Hs@A2-Z}-#6Z^hFvHL3% zT!Q8MVd!unx_t)RKdj3W_gUU_N>3mQjft3yIQ!~EMz}2_-1*8vQpiGj(^MJJkztnd zyuQTY;xJo&;PkEXb30 zdAlSq#4wX^pYzO`TS2_QRzcxtR^Y#8cn}tZ09861hA1) z|I!Bnw;=lJXLVB%_7?OwU!CfhKw8r2T`_R$!(fmD4?Rqb%UZ1`W9Z%M2)GXD$oy^< zS;C`~Qyul)as-C2H5m4<|N1rx2l-(gdAMH+7X3|@e7>hLc>VLhaLs?Va@!tddwML( zI;8Q%rABwo{%0`|typu&7z?AvY{7`XC-GJAjALYeO);*nN1VCrYge>uDIL!JF{Ts5 z^S>ze8qyzCTf~S+2BqB#AVAdwg$^x{lHc z=^~DLQz-^%P bkI2i%`mC(=W+W(+i+@;>b$iK~d29X;fdRn= From 00d78e5c3f9c1430f17c94a026d0e301725bb1c2 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 19 Jan 2022 00:23:57 -0600 Subject: [PATCH 36/73] Fixed issue with spawning on Pyramid/HC Ledge with old man --- Rom.py | 2 +- data/base2current.bps | Bin 87368 -> 87379 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index c38b495c..78f6d2a2 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'fbdd4f1bf5722a38ce147b4584d6ccb8' +RANDOMIZERBASEHASH = 'a081f50ff839e1d9ef997087a2dfd22f' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 581c770e3f40a0898dd2049e31e06ee5192f3aa2..f6e717d7f2fbed944d33e06abd07c5f30cd9c700 100644 GIT binary patch delta 8877 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 Aj{pDw delta 8891 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 Ca-;eH From 054aa84270db9d8bbf36f9d9447955df8259fbbb Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 19 Jan 2022 00:42:02 -0600 Subject: [PATCH 37/73] Fixed start as bunny for Bomb Shop --- Rom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index 78f6d2a2..a6a6dfa9 100644 --- a/Rom.py +++ b/Rom.py @@ -818,7 +818,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): lh_name = 'Big Bomb Shop' links_house = world.get_region(lh_name, player) if should_be_bunny(links_house, world.mode[player]): - rom.write_bytes(0x13fff0, [0x04, 0x01]) + rom.write_bytes(0x13fff0, [0x04 if lh_name == 'Links House' else 0x1C, 0x01]) old_man_house = world.get_region('Old Man House', player) if should_be_bunny(old_man_house, world.mode[player]): From 2cd0fa3b5c76e7fa90122c2204bd76a082de946f Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 19 Jan 2022 01:39:36 -0600 Subject: [PATCH 38/73] Fixed world flag on Mountain Cave start --- Rom.py | 2 +- data/base2current.bps | Bin 87379 -> 87396 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index a6a6dfa9..bcc2a3c6 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'a081f50ff839e1d9ef997087a2dfd22f' +RANDOMIZERBASEHASH = '3e62bf77f3b6be521c932b66a9931602' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index f6e717d7f2fbed944d33e06abd07c5f30cd9c700..765a831ebebba7b41f225a7cc86d55897a57594c 100644 GIT binary patch delta 138 zcmV;50CoSzkbwxB^Q95uFsT=XUGCrlmqP}d sg~Bjjm Date: Wed, 19 Jan 2022 01:44:00 -0600 Subject: [PATCH 39/73] Restoring vanilla terrain for glitched Inverted modes --- Rules.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Rules.py b/Rules.py index ceabdf72..c0904de9 100644 --- a/Rules.py +++ b/Rules.py @@ -887,6 +887,8 @@ def ow_rules(world, player): set_rule(world.get_entrance('West Dark Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Bubble Boy Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('West Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Spectacle Rock Approach', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player)) + set_rule(world.get_entrance('Spectacle Rock Leave', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player)) if not world.is_tile_swapped(0x05, player): set_rule(world.get_entrance('East Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player)) @@ -919,6 +921,7 @@ def ow_rules(world, player): set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) set_rule(world.get_entrance('TR Pegs Ledge Drop', player), lambda state: False) set_rule(world.get_entrance('TR Pegs Ledge Leave', player), lambda state: state.has('Hammer', player) and state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) + set_rule(world.get_entrance('Turtle Rock Tail Ledge Drop', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) if not world.is_tile_swapped(0x0a, player): set_rule(world.get_entrance('Mountain Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) @@ -967,8 +970,8 @@ def ow_rules(world, player): set_rule(world.get_entrance('Graveyard Ledge Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) set_rule(world.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) else: - set_rule(world.get_entrance('Graveyard Ladder (Top)', player), lambda state: state.has_Pearl(player)) - set_rule(world.get_entrance('Graveyard Ladder (Bottom)', player), lambda state: state.has_Pearl(player)) + set_rule(world.get_entrance('Graveyard Ladder (Top)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player)) + set_rule(world.get_entrance('Graveyard Ladder (Bottom)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player)) set_rule(world.get_entrance('Dark Graveyard Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Dark Graveyard Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Dark Graveyard Grave Mirror Spot', player), lambda state: state.has_Mirror(player)) @@ -1128,6 +1131,8 @@ def ow_rules(world, player): set_rule(world.get_entrance('Misery Mire Blocked Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Misery Mire Main Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Misery Mire Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) + set_rule(world.get_entrance('Checkerboard Ledge Approach', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) + set_rule(world.get_entrance('Checkerboard Ledge Leave', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) if not world.is_tile_swapped(0x32, player): set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has_Mirror(player)) @@ -1135,6 +1140,8 @@ def ow_rules(world, player): else: set_rule(world.get_entrance('Stumpy Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Stumpy Bush Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Cave 45 Inverted Approach', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) + set_rule(world.get_entrance('Cave 45 Inverted Leave', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) if not world.is_tile_swapped(0x33, player): set_rule(world.get_entrance('C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player)) @@ -1168,6 +1175,7 @@ def ow_rules(world, player): set_rule(world.get_entrance('Ice Lake Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Ice Palace Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Ice Palace Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) + set_rule(world.get_entrance('Lake Hylia Island Pier', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) if not world.is_tile_swapped(0x37, player): set_rule(world.get_entrance('Ice Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) @@ -1181,6 +1189,8 @@ def ow_rules(world, player): set_rule(world.get_entrance('Swamp Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Swamp Nook Southeast Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Swamp Nook Pegs Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Desert Pass Ladder (South)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) + set_rule(world.get_entrance('Desert Pass Ladder (North)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) if not world.is_tile_swapped(0x3b, player): set_rule(world.get_entrance('Dam Mirror Spot', player), lambda state: state.has_Mirror(player)) From b01a6f7cd85990df0e4ef1962697f8d7c57a7f2c Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 19 Jan 2022 01:46:08 -0600 Subject: [PATCH 40/73] Removing unnecessary indirect connections --- EntranceShuffle.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 90f78451..82c9743f 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -2296,24 +2296,24 @@ one_way_ledges = { indirect_connections = { 'Turtle Rock Ledge': 'Turtle Rock', - 'Big Bomb Shop': 'Pyramid Fairy', + #'Big Bomb Shop': 'Pyramid Fairy', #'East Dark World': 'Pyramid Fairy', 'Pyramid Area': 'Pyramid Fairy', # HC Ledge/Courtyard #'Dark Desert': 'Pyramid Fairy', - 'Misery Mire Area': 'Pyramid Fairy', # Desert/Checkerboard Ledge + #'Misery Mire Area': 'Pyramid Fairy', # Desert/Checkerboard Ledge #'West Dark World': 'Pyramid Fairy', - 'Dark Chapel Area': 'Pyramid Fairy', # Bonk Rocks - 'Dark Graveyard North': 'Pyramid Fairy', # Graveyard Ledge/Kings Tomb + #'Dark Chapel Area': 'Pyramid Fairy', # Bonk Rocks + #'Dark Graveyard North': 'Pyramid Fairy', # Graveyard Ledge/Kings Tomb #'South Dark World': 'Pyramid Fairy', - 'Dig Game Ledge': 'Pyramid Fairy', # Brother House Left - 'Stumpy Approach Area': 'Pyramid Fairy', # Cave 45 + #'Dig Game Ledge': 'Pyramid Fairy', # Brother House Left + #'Stumpy Approach Area': 'Pyramid Fairy', # Cave 45 # Inverted Cases #'Light World': 'Pyramid Fairy', - 'Lost Woods West Area': 'Pyramid Fairy', # Skull Woods Back - 'East Death Mountain (Top East)': 'Pyramid Fairy', # Floating Island - 'Blacksmith Area': 'Pyramid Fairy', # Hammerpegs - 'Forgotten Forest Area': 'Pyramid Fairy', # Shield Shop - 'Desert Area': 'Pyramid Fairy', # Mire Area + #'Lost Woods West Area': 'Pyramid Fairy', # Skull Woods Back + #'East Death Mountain (Top East)': 'Pyramid Fairy', # Floating Island + #'Blacksmith Area': 'Pyramid Fairy', # Hammerpegs + #'Forgotten Forest Area': 'Pyramid Fairy', # Shield Shop + #'Desert Area': 'Pyramid Fairy', # Mire Area 'Old Man Cave': 'Old Man S&Q' } # format: From 17b12bd5c779467f895744af4f2d56c77a47e048 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 19 Jan 2022 01:48:17 -0600 Subject: [PATCH 41/73] Restoring vanilla terrain for glitched Inverted modes --- Rom.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Rom.py b/Rom.py index bcc2a3c6..743d5409 100644 --- a/Rom.py +++ b/Rom.py @@ -1264,6 +1264,13 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): gametype |= 0x01 # enemizer rom.write_byte(0x180211, gametype) # Game type + warningflags = 0x00 # none + if world.logic[player] in ['owglitches', 'nologic']: + warningflags |= 0x20 + if world.logic[player] in ['minorglitches', 'owglitches', 'nologic']: + warningflags |= 0x40 + rom.write_byte(0x180212, warningflags) # Warning flags + # assorted fixes rom.write_byte(0x1800A2, 0x01 if world.fix_fake_world else 0x00) # remain in real dark world when dying in dark world dungeon before killing aga1 rom.write_byte(0x180169, 0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence. From a61a3d3693bad8cbdffc6524b6bdfd701a4e8351 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 19 Jan 2022 02:31:54 -0600 Subject: [PATCH 42/73] Fixed Hera boss music to correctly read boss defeated flag --- Rom.py | 2 +- data/base2current.bps | Bin 87396 -> 87514 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index 743d5409..0d948695 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '3e62bf77f3b6be521c932b66a9931602' +RANDOMIZERBASEHASH = 'ea4215dbf86da55ffa1255fa5e687b62' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 765a831ebebba7b41f225a7cc86d55897a57594c..138034ba6448e44a08823633503bfcbaeb7f9a05 100644 GIT binary patch delta 6935 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 M>u*Tbm-&GV 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 P&^T%t!dxU^c5<_m!;#GHTh!zly4(!g?1#+_l zkvBOjYV4V}g=N!Q=%_?3*$lQizWS@=X0>e;oi>liD|yny{DdDI+VR@}t?=%6&QZxh z*NzvKjML62ng+6t+`@cwOQ*DY`xrPY&u((>bx{N@u!4CPg?InaHW+nJTQN9ntbDQ)@9Wn9W@ z>u?~*%C5zPF2A{^jkPo=YudZZX;(sZ#IL;za6)&oJ-@m4LYXe%cs9$UdEb{WAR=Ma znbFRnWp+X9gDC39(b;hD%yt-gwx4fKKqwg2>C5}}i$^fFa}VZC!mZAPQQ78K7=?$J zUt?5Ah`AW0Oq!P}vl7*`>q0`aSwDJ5to@XW`8`IRj5UA2sME38tUvt*Qo9sbk{T{_ ztrhtybm3AeTB;ol6VLq-@O{a+qEeg^22-WMlrV%U4WZN_<}VSdBsd$s{wdZkh_VNn zuOd{ognA^QRs@-gP|7BuW(Jwz%1=^JR0(a+9`YtG;;{RtP|<(Oo_Z6v!zoz=IG@Ld zG^HpOhEsRL&0A1vCT@O=P_uC=3x~AxU*p#h>Je_nc+{`B`68md2$i&@e!*Fi7p5@39P} zvO~-Qlv)--JqV#>p|H1mI2sDQ-7&%^0?HOjWekVEx@SUG&ko+i;yG}wXPP)F+k73R zNIG&`jCv5oPP!jgP<~`Lk1~duaR5zN1w%`I*1mle?|47u!uLdUTm zj)LU#^4h6E4-V{hSobHtD6R2w^xExXLbA<5;M7^xL zfN<-Sm`8$=^wXAC1{0JRR@?kXu8Jqfc%aEZO%IzCPpFUUOUPwSin2&zfbYp83A>7v z+IZDSK*3pNqNIK3z=QTWKZ18V& ze7jep)hExXtAP}1TlMoczG#}e@kM3W7TsEM#y)F@nocBCrl(* zUvuE_ISBpvOa6*;5?@&I^HlHF&R+4`y;C zX#58f<4z}H!}etDS+j=1CYjH}-s?VIhq@S_yyEN^TFe7!w9-`Tl`gPe--SglfF(DA zV|};2s!WuX%_4aFkd7P^vyWFN5OZ+Vzfd>;^Ztcy15gf!ZUlHo$6P1Jf}(M00}_vl zFcE@*w-6rPn2q5=`0{2bw$#zG=w=j(O?3wKtv8rsAQb)*_=O-&Lyn-mT`L+Vy)Cdg zu_N9VjHQ!YD;{zeBf_0u^10@wKVfUW zR;gXrkdO~+?tJOr(vwCzhiK>((Hi>u+0W}-*~9^566w+DaOzHkTT2feIHsaHc6#eC z>6~_N?|k7k*i+Xy{B40x{wVH(<_;wg8VyNzON1`dD#*n!PYS(vLmgL0iCM&Nm*L%A zC|tD0k+?3qWOv|pZL?!thP!0-W&F3d!z9g@4N38T7-pSAM`G4>CvC zdFiSvu=oBVOc)D)-&fB+L`9?NgRYoAb&B^O6ZNSQ58}xCJ;_0>$w9XFW|BfC(ggt? z#M$IVvDMN3mDSBY#p+~>eI(W|NpK>XW)nIG>v|jaKJs;4gBT&IGyhR`io5-!aPL8u zWV)l)jBs{n;>^xR?A0SDn6w+}br=z58&13BXdv@pANH^hLLRNbj{OXkk9J_$*FgL@ zOLFV_@A0VpjTw0{pn}~M{BPD1Z1FEazVF(%;i#^MN#R#rX0r1)9Jonc;FTWw;QrDVcD}CV&BRC zN9O)#ONrmYSF0o{(K^eY&r(IA_$j3-cU-Iw^tDWQ6N#c1VfEWlf>Coz^+6fX^!9+i zkC%w3^^4g}E~s9PE9((k2K&(-W}ilniLtEvpN97p_g*0R2=t;VvkdShjkz=meCYxPr-V9JMb zpUqo{vrKovDXCpzqqY0G3tF=O`An~khvy&ej4(Mw>mLft!^3MP5ANxC;KyC&cl+ce zA^S@Z^|WUFn$dRsj3SkL$Byc>H3#7J$3L)7J@D|8H?}ks-hT>qnwLc=IWHkmmXQCG zI|y?E%fFdO6ryc3iuRzQEh(RlaSkRWoL&u@mC@a06kB0b-vNGJGp_R42vWD3I z_-IHN{Zf@XR!(R6&`!@PN%nh=YUSo Date: Wed, 19 Jan 2022 03:43:37 -0600 Subject: [PATCH 43/73] Restored vanilla Ice Palace terrain for Inverted --- OWEdges.py | 5 +++-- OverworldShuffle.py | 6 +++--- Regions.py | 5 +++-- Rom.py | 5 +++-- Rules.py | 1 + data/base2current.bps | Bin 87514 -> 87420 bytes 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index 6905570f..95c546ad 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -820,6 +820,7 @@ OWTileRegions = bidict({ 'Lake Hylia Central Island': 0x35, 'Lake Hylia Island': 0x35, 'Lake Hylia Water': 0x35, + 'Lake Hylia Water D': 0x35, 'Ice Cave Area': 0x37, @@ -1584,6 +1585,7 @@ OWExitTypes = { 'Lake Hylia West Pier', 'Lake Hylia Northeast Water Drop', 'Lake Hylia East Pier', + 'Lake Hylia Water D Entry', 'Desert Pass Ladder (South)', 'Desert Pass Rocks (North)', 'Desert Pass Rocks (South)', @@ -1639,8 +1641,6 @@ OWExitTypes = { 'Ice Lake Northeast Pier', 'Ice Lake Northeast Pier Hop', 'Ice Lake Moat Water Entry', - 'Ice Palace Approach', - 'Ice Palace Leave', 'Bomber Corner Water Drop', 'Bomber Corner Pier' ], @@ -1760,6 +1760,7 @@ OWExitTypes = { 'Ice Lake Southeast Mirror Spot', 'Ice Lake Northeast Mirror Spot', 'Ice Palace Mirror Spot', + 'Ice Lake Moat Mirror Spot', 'Shopping Mall Mirror Spot', 'Swamp Nook Mirror Spot', 'Swamp Nook Southeast Mirror Spot', diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 40c98c36..0e14bb49 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1208,6 +1208,7 @@ mandatory_connections = [# Intra-tile OW Connections ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), ('Lake Hylia West Pier', 'Lake Hylia Area'), ('Lake Hylia East Pier', 'Lake Hylia Northeast Bank'), + ('Lake Hylia Water D Entry', 'Lake Hylia Water'), #flippers ('Desert Pass Ledge Drop', 'Desert Pass Area'), ('Desert Pass Rocks (North)', 'Desert Pass Southeast'), #glove ('Desert Pass Rocks (South)', 'Desert Pass Area'), #glove @@ -1669,14 +1670,13 @@ ow_connections = { ('Lake Hylia Teleporter', 'Ice Palace Area') ], [ ('Lake Hylia Island Pier', 'Lake Hylia Island'), - ('Ice Palace Approach', 'Ice Palace Area'), - ('Ice Palace Leave', 'Ice Lake Moat'), ('Ice Lake Mirror Spot', 'Ice Lake Area'), ('Ice Lake Southwest Mirror Spot', 'Ice Lake Ledge (West)'), ('Ice Lake Southeast Mirror Spot', 'Ice Lake Ledge (East)'), ('Ice Lake Northeast Mirror Spot', 'Ice Lake Northeast Bank'), ('Ice Palace Mirror Spot', 'Ice Palace Area'), - ('Ice Palace Teleporter', 'Lake Hylia Central Island') + ('Ice Lake Moat Mirror Spot', 'Ice Lake Moat'), + ('Ice Palace Teleporter', 'Lake Hylia Water D') ]), 0x37: ([ ('Ice Cave Mirror Spot', 'Ice Cave Area') diff --git a/Regions.py b/Regions.py index 2cf2783e..f94599a8 100644 --- a/Regions.py +++ b/Regions.py @@ -112,6 +112,7 @@ def create_regions(world, player): create_lw_region(player, 'Lake Hylia Central Island', None, ['Lake Hylia Central Water Drop', 'Capacity Upgrade', 'Ice Palace Mirror Spot', 'Lake Hylia Teleporter']), create_lw_region(player, 'Lake Hylia Island', ['Lake Hylia Island'], ['Lake Hylia Island Water Drop']), create_lw_region(player, 'Lake Hylia Water', None, ['Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia West Pier', 'Lake Hylia East Pier', 'Lake Hylia NC', 'Lake Hylia EC', 'Lake Hylia Whirlpool'], Terrain.Water), + create_lw_region(player, 'Lake Hylia Water D', None, ['Lake Hylia Water D Entry', 'Ice Lake Moat Mirror Spot'], Terrain.Water), create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Shopping Mall Mirror Spot', 'Ice Cave SE', 'Ice Cave SW']), create_lw_region(player, 'Desert Pass Area', ['Middle Aged Man'], ['Desert Pass Ladder (South)', 'Middle Aged Man', 'Desert Fairy', '50 Rupee Cave', 'Swamp Nook Mirror Spot', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']), create_lw_region(player, 'Middle Aged Man', ['Purple Chest'], None), @@ -212,8 +213,8 @@ def create_regions(world, player): create_dw_region(player, 'Ice Lake Ledge (West)', None, ['Ice Lake Southwest Water Drop', 'South Shore Mirror Spot', 'Ice Lake WS']), create_dw_region(player, 'Ice Lake Ledge (East)', None, ['Ice Lake Southeast Water Drop', 'South Shore East Mirror Spot', 'Ice Lake ES']), create_dw_region(player, 'Ice Lake Water', None, ['Ice Lake Northeast Pier', 'Ice Lake Moat Bomb Jump', 'Lake Hylia Island Mirror Spot', 'Ice Lake NC', 'Ice Lake EC'], Terrain.Water), - create_dw_region(player, 'Ice Lake Moat', None, ['Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Hop', 'Ice Palace Approach', 'Lake Hylia Water Mirror Spot']), - create_dw_region(player, 'Ice Palace Area', None, ['Ice Palace Leave', 'Ice Palace', 'Ice Palace Teleporter', 'Lake Hylia Central Island Mirror Spot']), + create_dw_region(player, 'Ice Lake Moat', None, ['Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Hop', 'Lake Hylia Water Mirror Spot']), + create_dw_region(player, 'Ice Palace Area', None, ['Ice Palace', 'Ice Palace Teleporter', 'Lake Hylia Central Island Mirror Spot']), create_dw_region(player, 'Shopping Mall Area', None, ['Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'Ice Cave Mirror Spot', 'Shopping Mall SW', 'Shopping Mall SE']), create_dw_region(player, 'Swamp Nook Area', None, ['Desert Pass Ledge Mirror Spot', 'Desert Pass Mirror Spot', 'Swamp Nook EC', 'Swamp Nook ES']), create_dw_region(player, 'Swamp Area', None, ['Swamp Palace', 'Dam Mirror Spot', 'Swamp WC', 'Swamp WS', 'Swamp NC', 'Swamp EC']), diff --git a/Rom.py b/Rom.py index 0d948695..1bcea73f 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'ea4215dbf86da55ffa1255fa5e687b62' +RANDOMIZERBASEHASH = 'b300438a7242825e33300f9d155814ef' class JsonRom(object): @@ -2682,7 +2682,8 @@ def set_inverted_mode(world, player, rom, inverted_buffer): rom.write_bytes(snes_to_pc(0x1BD1D8), [0xA8, 0x02, 0x82, 0xFF, 0xFF]) # add warp under rock rom.write_byte(snes_to_pc(0x1BC5B1), 0x00) # remove secret portal if world.is_tile_swapped(0x35, player): - rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) # add warp under rock + #rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) # add warp under rock + rom.write_bytes(snes_to_pc(0x1BC85A), [0x52, 0x13, 0x82]) # add warp under rock rom.write_byte(snes_to_pc(0x1BC5C7), 0x00) # remove secret portal # apply inverted map changes diff --git a/Rules.py b/Rules.py index c0904de9..f1c216a3 100644 --- a/Rules.py +++ b/Rules.py @@ -825,6 +825,7 @@ def default_rules(world, player): set_rule(world.get_entrance('Lake Hylia Northeast Water Drop', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Lake Hylia Central Water Drop', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Lake Hylia Island Water Drop', player), lambda state: state.has('Flippers', player)) + set_rule(world.get_entrance('Lake Hylia Water D Entry', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Ice Cave SW', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Octoballoon Water Drop', player), lambda state: state.has('Flippers', player)) set_rule(world.get_entrance('Octoballoon Waterfall Water Drop', player), lambda state: state.has('Flippers', player)) diff --git a/data/base2current.bps b/data/base2current.bps index 138034ba6448e44a08823633503bfcbaeb7f9a05..efdb59ccceb0b7caa41af37d383dd6b05c25e98b 100644 GIT binary patch delta 2748 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 delta 2891 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 MOwA2R!G2HbzdTv|EC2ui From 78a7d5f850e8c2d20c209e4e8b34794790ff0023 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 19 Jan 2022 04:09:00 -0600 Subject: [PATCH 44/73] Version bump 0.2.5.0 --- CHANGELOG.md | 19 +++++++++++++++++++ OverworldShuffle.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f4e4a34..f5edc88f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +### 0.2.5.0 +- Many updates to Inverted OW Terrain: + - Links House start now spawns in Big Bomb Shop + - Old Man Cave/Bumper Cave returned to vanilla + - Mountain Cave S+Q now spawns in his usual Cave + - Flute Spot 1 is moved to Top of Dark Death Mountain + - Ladder is removed from West Dark Death Mountain + - When finding Flute, it comes pre-activated (will hear SFX on collecting) + - Spiral and Mimic Cave are now bridged together + - TR Peg Puzzle is restored but instead reveals a ladder + - Houlihan now exits same place as Big Bomb Shop does (OWR branch always had this) + - Ice Palace has been re-sealed to vanilla, portal moved to outer edge of moat + - Glitched modes will now use vanilla terrain except where necessary +- Fixed errors with OW Layout Shuffle +- 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~~ + ### 0.2.4.0 - Added Guaranteed OWR Reachability - Fixed incorrect parity calc for Whirlpool Shuffle diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 0e14bb49..e825d799 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -5,7 +5,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl from Regions import mark_dark_world_regions, mark_light_world_regions from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel -__version__ = '0.2.4.0-u' +__version__ = '0.2.5.0-u' def link_overworld(world, player): # setup mandatory connections From 09700d2d67c41a41950e9d01e1a17e75c04e66db Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 19 Jan 2022 22:09:18 -0600 Subject: [PATCH 45/73] Fixed issue with Inverted Kak Portal missing rule --- Rules.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Rules.py b/Rules.py index f1c216a3..3e5ef987 100644 --- a/Rules.py +++ b/Rules.py @@ -949,6 +949,7 @@ def ow_rules(world, player): set_rule(world.get_entrance('Skull Woods Pass East Top Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Skull Woods Pass Portal Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Skull Woods Pass East Bottom Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('West Dark World Teleporter', player), lambda state: state.can_lift_rocks(player)) if not world.is_tile_swapped(0x11, player): set_rule(world.get_entrance('Kakariko Fortune Mirror Spot', player), lambda state: state.has_Mirror(player)) From 0e700098d91f5314f1c0180327a271cdb3867309 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 20 Jan 2022 01:12:45 -0600 Subject: [PATCH 46/73] Version bump 0.2.5.1 --- CHANGELOG.md | 3 +++ OverworldShuffle.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5edc88f..dd5f3cb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +### 0.2.5.1 +- Fixed missing rule for Inverted VoO Portal access + ### 0.2.5.0 - Many updates to Inverted OW Terrain: - Links House start now spawns in Big Bomb Shop diff --git a/OverworldShuffle.py b/OverworldShuffle.py index e825d799..8d432988 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -5,7 +5,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl from Regions import mark_dark_world_regions, mark_light_world_regions from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel -__version__ = '0.2.5.0-u' +__version__ = '0.2.5.1-u' def link_overworld(world, player): # setup mandatory connections From 3c2b009aab19b295c7a5999f4bcb23baa8fa6f59 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 21 Jan 2022 09:52:20 -0600 Subject: [PATCH 47/73] Added Spiral Mimic Ledge Extend region to list of isolated regions --- OverworldShuffle.py | 1 + 1 file changed, 1 insertion(+) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 8d432988..529661da 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1862,6 +1862,7 @@ default_connections = [#('Lost Woods NW', 'Master Sword Meadow SC'), isolated_regions = [ 'Death Mountain Floating Island', 'Mimic Cave Ledge', + 'Spiral Mimic Ledge Extend', 'Mountain Entry Ledge', 'Maze Race Prize', 'Maze Race Ledge', From c3e288f40fe152c731e321469bfa3a808d7e891f Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 26 Jan 2022 09:49:59 -0600 Subject: [PATCH 48/73] Added starting boots and psuedoboots options to example mystery yaml --- mystery_example.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mystery_example.yml b/mystery_example.yml index 3869fef9..dd89ca3a 100644 --- a/mystery_example.yml +++ b/mystery_example.yml @@ -153,6 +153,13 @@ easy: 1 hard: 1 expert: 0 + pseudoboots: + on: 1 + off: 0 + startinventory: + "Pegasus Boots": + on: 0 + off: 1 rom: quickswap: on: 1 From 220c4b5a70f23269318999e6c2fcbcf0def89393 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 28 Jan 2022 00:06:51 -0600 Subject: [PATCH 49/73] Version bump 0.2.5.2 --- OverworldShuffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 529661da..66d63897 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -5,7 +5,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl from Regions import mark_dark_world_regions, mark_light_world_regions from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel -__version__ = '0.2.5.1-u' +__version__ = '0.2.5.2-u' def link_overworld(world, player): # setup mandatory connections From b53fd17e436a0fa61905c318f4f9f36911b49f14 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 28 Jan 2022 00:26:53 -0600 Subject: [PATCH 50/73] Added Light Hype Fairy to bombable doors --- Rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules.py b/Rules.py index 3e5ef987..21a0ffc6 100644 --- a/Rules.py +++ b/Rules.py @@ -597,7 +597,7 @@ def global_rules(world, player): def bomb_rules(world, player): bonkable_doors = ['Two Brothers House Exit (West)', 'Two Brothers House Exit (East)'] # Technically this is incorrectly defined, but functionally the same as what is intended. - bombable_doors = ['Ice Rod Cave', 'Light World Bomb Hut', 'Light World Death Mountain Shop', 'Mini Moldorm Cave', + bombable_doors = ['Ice Rod Cave', 'Light World Bomb Hut', 'Light World Death Mountain Shop', 'Light Hype Fairy', 'Mini Moldorm Cave', 'Hookshot Cave Back to Middle', 'Hookshot Cave Front to Middle', 'Hookshot Cave Middle to Front','Hookshot Cave Middle to Back', 'Dark Lake Hylia Ledge Fairy', 'Hype Cave', 'Brewery'] for entrance in bonkable_doors: From ee215dbfa7703cadc7a846c3bf60d86be26d0459 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 2 Feb 2022 19:50:41 -0600 Subject: [PATCH 51/73] Fixed issue with Links House swapped in OW Tile Swap --- OverworldShuffle.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 66d63897..8b847002 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -67,8 +67,12 @@ def link_overworld(world, player): # move both sets if parallel == IsParallel.Yes and not (all(edge in orig_swaps for edge in map(getParallel, forward_set)) and all(edge in orig_swaps for edge in map(getParallel, back_set))): raise Exception('Cannot move a parallel edge without the other') - new_groups[(OpenStd.Open, WorldType((int(wrld) + 1) % 2), dir, terrain, parallel, count)][0].append(forward_set) - new_groups[(OpenStd.Open, WorldType((int(wrld) + 1) % 2), dir, terrain, parallel, count)][1].append(back_set) + new_mode = OpenStd.Open + if tuple((OpenStd.Open, WorldType((int(wrld) + 1) % 2), dir, terrain, parallel, count)) not in new_groups.keys(): + # when Links House tile is swapped, the DW edges need to get put into existing Standard group + new_mode = OpenStd.Standard + new_groups[(new_mode, WorldType((int(wrld) + 1) % 2), dir, terrain, parallel, count)][0].append(forward_set) + new_groups[(new_mode, WorldType((int(wrld) + 1) % 2), dir, terrain, parallel, count)][1].append(back_set) for edge in forward_set: swaps.remove(edge) for edge in back_set: From e9fd006d2b1e3bffe83ef77556c93480b9782d79 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 2 Feb 2022 19:53:15 -0600 Subject: [PATCH 52/73] Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world --- EntranceShuffle.py | 6 +++--- Rom.py | 17 ++++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 82c9743f..d30404cc 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -90,11 +90,11 @@ def link_entrances(world, player): for entrancename, exitname in default_skulldrop_connections: connect_logical(world, entrancename, exitname, player, False) - if not invFlag: - for entrancename, exitname in open_default_dungeon_connections: + if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) and (0x03 not in world.owswaps[player][0]) == invFlag: + for entrancename, exitname in inverted_default_dungeon_connections: connect_logical(world, entrancename, exitname, player, True) else: - for entrancename, exitname in inverted_default_dungeon_connections: + for entrancename, exitname in open_default_dungeon_connections: connect_logical(world, entrancename, exitname, player, True) elif world.shuffle[player] == 'dungeonssimple': suppress_spoiler = False diff --git a/Rom.py b/Rom.py index 1bcea73f..cb2fda68 100644 --- a/Rom.py +++ b/Rom.py @@ -2520,13 +2520,16 @@ def set_inverted_mode(world, player, rom, inverted_buffer): write_int16(rom, snes_to_pc(0x02D998), 0x0000) write_int16(rom, snes_to_pc(0x02D9A6), 0x005A) rom.write_byte(snes_to_pc(0x02D9B3), 0x12) - - if world.shuffle[player] == 'vanilla': - rom.write_byte(0xDBB73 + 0x23, 0x37) # switch AT and GT - rom.write_byte(0xDBB73 + 0x36, 0x24) - if world.doorShuffle[player] == 'vanilla' or world.intensity[player] < 3: - write_int16(rom, 0x15AEE + 2*0x38, 0x00E0) - write_int16(rom, 0x15AEE + 2*0x25, 0x000C) + + # switch AT and GT + if world.shuffle[player] == 'vanilla' and \ + (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) and \ + (0x03 not in world.owswaps[player][0]) == world.mode[player] == 'inverted': + rom.write_byte(0xDBB73 + 0x23, 0x37) + rom.write_byte(0xDBB73 + 0x36, 0x24) + if world.doorShuffle[player] == 'vanilla' or world.intensity[player] < 3: + write_int16(rom, 0x15AEE + 2*0x38, 0x00E0) + write_int16(rom, 0x15AEE + 2*0x25, 0x000C) if world.is_tile_swapped(0x05, player): From 7e7efb053388845f8f5a2ab290dd557b31bf3d9d Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 3 Feb 2022 00:25:13 -0600 Subject: [PATCH 53/73] Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world --- Rules.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Rules.py b/Rules.py index 21a0ffc6..ecff7ba4 100644 --- a/Rules.py +++ b/Rules.py @@ -854,12 +854,13 @@ def default_rules(world, player): def ow_rules(world, player): - if world.mode[player] != 'inverted': + if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) and \ + (0x03 not in world.owswaps[player][0]) == world.mode[player] == 'inverted': + set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) + else: set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has_beam_sword(player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle set_rule(world.get_entrance('GT Entry Approach', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) set_rule(world.get_entrance('GT Entry Leave', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player) or state.world.shuffle[player] in ('restricted', 'full', 'lite', 'lean', 'crossed', 'insanity')) - else: - set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) if not world.is_tile_swapped(0x00, player): set_rule(world.get_entrance('Lost Woods East Mirror Spot', player), lambda state: state.has_Mirror(player)) @@ -1524,7 +1525,8 @@ def swordless_rules(world, player): set_rule(world.get_location('Ganon', player), lambda state: state.has('Hammer', player) and state.has_fire_source(player) and state.has('Silver Arrows', player) and state.can_shoot_arrows(player) and state.has_crystals(world.crystals_needed_for_ganon[player], player)) set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has('Hammer', player)) # need to damage ganon to get tiles to drop - if world.mode[player] != 'inverted': + if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) and \ + (0x03 not in world.owswaps[player][0]) == world.mode[player] == 'inverted'): set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!) From 392cb7187c7371db1d94f5fc82597a90b536f609 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 3 Feb 2022 06:12:18 -0600 Subject: [PATCH 54/73] Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world --- EntranceShuffle.py | 2 +- Rom.py | 13 +++++++------ Rules.py | 6 ++---- data/base2current.bps | Bin 87420 -> 87439 bytes 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index d30404cc..79bc43f9 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -90,7 +90,7 @@ def link_entrances(world, player): for entrancename, exitname in default_skulldrop_connections: connect_logical(world, entrancename, exitname, player, False) - if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) and (0x03 not in world.owswaps[player][0]) == invFlag: + if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag): for entrancename, exitname in inverted_default_dungeon_connections: connect_logical(world, entrancename, exitname, player, True) else: diff --git a/Rom.py b/Rom.py index cb2fda68..b7981fb9 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'b300438a7242825e33300f9d155814ef' +RANDOMIZERBASEHASH = '9ff49ef63fdddeb32de09646bd459bf8' class JsonRom(object): @@ -877,7 +877,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x138006, 1) # swap in non-ER Lobby Shuffle Inverted - but only then - if world.mode[player] == 'inverted' and world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla' and world.shuffle[player] == 'vanilla': + if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted') and \ + world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla' and world.shuffle[player] == 'vanilla': aga_portal = world.get_portal('Agahnims Tower', player) gt_portal = world.get_portal('Ganons Tower', player) aga_portal.exit_offset, gt_portal.exit_offset = gt_portal.exit_offset, aga_portal.exit_offset @@ -1286,6 +1287,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] or world.goal[player] == 'trinity' else 0x00) # pre-open Pyramid Hole rom.write_byte(0x18008C, 0x01 if world.crystals_needed_for_gt[player] == 0 else 0x00) # GT pre-opened if crystal requirement is 0 + rom.write_byte(0x18008F, 0x01 if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted') else 0x00) # AT/GT swapped rom.write_byte(0xF5D73, 0xF0) # bees are catchable rom.write_byte(0xF5F10, 0xF0) # bees are catchable rom.write_byte(0x180086, 0x00 if world.aga_randomness else 0x01) # set blue ball and ganon warp randomness @@ -2168,7 +2170,7 @@ def write_strings(rom, world, player, team): entrances_to_hint = {} entrances_to_hint.update(InconvenientDungeonEntrances) if world.shuffle_ganon: - if world.mode[player] == 'inverted': + if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) else: entrances_to_hint.update({'Ganons Tower': 'Ganon\'s Tower'}) @@ -2201,7 +2203,7 @@ 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.mode[player] == 'inverted': + if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): entrances_to_hint.update({'Ganons Tower': 'The dark mountain tower'}) else: entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) @@ -2523,8 +2525,7 @@ def set_inverted_mode(world, player, rom, inverted_buffer): # switch AT and GT if world.shuffle[player] == 'vanilla' and \ - (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) and \ - (0x03 not in world.owswaps[player][0]) == world.mode[player] == 'inverted': + (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): rom.write_byte(0xDBB73 + 0x23, 0x37) rom.write_byte(0xDBB73 + 0x36, 0x24) if world.doorShuffle[player] == 'vanilla' or world.intensity[player] < 3: diff --git a/Rules.py b/Rules.py index ecff7ba4..50d808b0 100644 --- a/Rules.py +++ b/Rules.py @@ -854,8 +854,7 @@ def default_rules(world, player): def ow_rules(world, player): - if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) and \ - (0x03 not in world.owswaps[player][0]) == world.mode[player] == 'inverted': + if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) else: set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has_beam_sword(player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle @@ -1525,8 +1524,7 @@ def swordless_rules(world, player): set_rule(world.get_location('Ganon', player), lambda state: state.has('Hammer', player) and state.has_fire_source(player) and state.has('Silver Arrows', player) and state.can_shoot_arrows(player) and state.has_crystals(world.crystals_needed_for_ganon[player], player)) set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has('Hammer', player)) # need to damage ganon to get tiles to drop - if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) and \ - (0x03 not in world.owswaps[player][0]) == world.mode[player] == 'inverted'): + if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted')): set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!) diff --git a/data/base2current.bps b/data/base2current.bps index efdb59ccceb0b7caa41af37d383dd6b05c25e98b..d588f66b3b9c808ccf8ec17e3a8522db9a3095ca 100644 GIT binary patch delta 4858 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 Date: Thu, 3 Feb 2022 06:14:22 -0600 Subject: [PATCH 55/73] Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world --- Rom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index b7981fb9..55a1af05 100644 --- a/Rom.py +++ b/Rom.py @@ -1275,7 +1275,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # assorted fixes rom.write_byte(0x1800A2, 0x01 if world.fix_fake_world else 0x00) # remain in real dark world when dying in dark world dungeon before killing aga1 rom.write_byte(0x180169, 0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence. - if world.mode[player] == 'inverted': + if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): rom.write_byte(0x180169, 0x02) # lock aga/ganon tower door with crystals in inverted rom.write_byte(0x180171, 0x01 if world.ganon_at_pyramid[player] else 0x00) # Enable respawning on pyramid after ganon death rom.write_byte(0x180173, 0x01) # Bob is enabled From 7d391da21d26b2c51a2708e6270f2ee709853a1e Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 3 Feb 2022 06:35:54 -0600 Subject: [PATCH 56/73] Added Flute Spots to spoiler log --- BaseClasses.py | 12 ++++++++++++ OverworldShuffle.py | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/BaseClasses.py b/BaseClasses.py index 7e17d469..e431cb4a 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -3053,6 +3053,18 @@ class Spoiler(object): if self.overworlds: outfile.write('\n\nOverworld:\n\n') + + # flute shuffle + for player in range(1, self.world.players + 1): + if ('flute', player) in self.maps: + outfile.write('Flute Spots:\n') + break + for player in range(1, self.world.players + 1): + if ('flute', player) in self.maps: + if self.world.players > 1: + outfile.write(str('(Player ' + str(player) + ')\n')) # player name + outfile.write(self.maps[('flute', player)]['text'] + '\n\n') + # overworld tile swaps for player in range(1, self.world.players + 1): if ('swaps', player) in self.maps: diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 8b847002..4328101f 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -420,6 +420,24 @@ def link_overworld(world, player): world.owflutespots[player] = new_spots connect_flutes(new_spots) + # update spoiler + s = list(map(lambda x: ' ' if x not in new_spots else 'F', [i for i in range(0x40)])) + text_output = tile_swap_spoiler_table.replace('s', '%s') % ( s[0x02], s[0x07], + s[0x00], s[0x03], s[0x05], + s[0x00], s[0x02],s[0x03], s[0x05], s[0x07], s[0x0a], s[0x0f], + s[0x0a], s[0x0f], + s[0x10],s[0x11],s[0x12],s[0x13],s[0x14],s[0x15],s[0x16],s[0x17], s[0x10],s[0x11],s[0x12],s[0x13],s[0x14],s[0x15],s[0x16],s[0x17], + s[0x18], s[0x1a],s[0x1b], s[0x1d],s[0x1e], + s[0x22], s[0x25], s[0x1a], s[0x1d], + s[0x28],s[0x29],s[0x2a],s[0x2b],s[0x2c],s[0x2d],s[0x2e],s[0x2f], s[0x18], s[0x1b], s[0x1e], + s[0x30], s[0x32],s[0x33],s[0x34],s[0x35], s[0x37], s[0x22], s[0x25], + s[0x3a],s[0x3b],s[0x3c], s[0x3f], + s[0x28],s[0x29],s[0x2a],s[0x2b],s[0x2c],s[0x2d],s[0x2e],s[0x2f], + s[0x32],s[0x33],s[0x34], s[0x37], + s[0x30], s[0x35], + s[0x3a],s[0x3b],s[0x3c], s[0x3f]) + world.spoiler.set_map('flute', text_output, new_spots, player) + def connect_custom(world, connected_edges, player): if hasattr(world, 'custom_overworld') and world.custom_overworld[player]: for edgename1, edgename2 in world.custom_overworld[player]: From 75d097c4b69866689ff7f24fb6703e2f3b841b4a Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 3 Feb 2022 06:46:06 -0600 Subject: [PATCH 57/73] Changed GT/AT swap in Mixed OW to prioritize leaving AT vanilla unless GT is the only one in the starting world --- EntranceShuffle.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 79bc43f9..e21aca8a 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -288,7 +288,7 @@ def link_entrances(world, player): caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not invFlag else 'Agahnims Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: caves.append('Ganons Tower Exit') @@ -361,7 +361,7 @@ def link_entrances(world, player): lw_dungeons.append(tuple(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)'))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not invFlag else 'Agahnims Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: dw_dungeons.append('Ganons Tower Exit') @@ -449,7 +449,7 @@ def link_entrances(world, player): Dungeon_Exits.append(tuple(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)'))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not invFlag else 'Agahnims Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: Dungeon_Exits.append('Ganons Tower Exit') @@ -499,7 +499,7 @@ def link_entrances(world, player): caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not invFlag else 'Agahnims Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: caves.append('Ganons Tower Exit') @@ -567,7 +567,7 @@ def link_entrances(world, player): caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not invFlag else 'Agahnims Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) 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) else: @@ -662,7 +662,7 @@ def link_entrances(world, player): world.ganon_at_pyramid[player] = False # check for Ganon's Tower location - if world.get_entrance('Ganons Tower' if not invFlag else 'Agahnims Tower', player).connected_region.name != 'Ganons Tower Portal' if not invFlag else 'GT Lobby': + if world.get_entrance('Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', player).connected_region.name != 'Ganons Tower Portal' if not invFlag else 'GT Lobby': world.ganonstower_vanilla[player] = False @@ -1235,7 +1235,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player): connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not invFlag else 'Agahnims Tower', 'Ganons Tower Exit', player) + connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', player) else: dungeon_exits.append('Ganons Tower Exit') From d60b4c61ce968b5fdb69f3f28b35f8c5dad00502 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 3 Feb 2022 06:54:42 -0600 Subject: [PATCH 58/73] Simplified AT/GT swap condition check --- BaseClasses.py | 3 +++ EntranceShuffle.py | 16 ++++++++-------- Rom.py | 14 ++++++-------- Rules.py | 4 ++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index e431cb4a..d836b1f3 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -304,6 +304,9 @@ class World(object): def is_tile_swapped(self, owid, player): return (self.mode[player] == 'inverted') != (owid in self.owswaps[player][0] and self.owMixed[player]) + def is_atgt_swapped(self, player): + return (0x03 in self.owswaps[player][0]) == (0x1b in self.owswaps[player][0]) == (self.mode[player] != 'inverted') + def is_bombshop_start(self, player): return self.is_tile_swapped(0x2c, player) and (self.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not self.shufflelinks[player]) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index e21aca8a..eb22b044 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -90,7 +90,7 @@ def link_entrances(world, player): for entrancename, exitname in default_skulldrop_connections: connect_logical(world, entrancename, exitname, player, False) - if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag): + if world.is_atgt_swapped[player]: for entrancename, exitname in inverted_default_dungeon_connections: connect_logical(world, entrancename, exitname, player, True) else: @@ -288,7 +288,7 @@ def link_entrances(world, player): caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', 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') @@ -361,7 +361,7 @@ def link_entrances(world, player): lw_dungeons.append(tuple(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)'))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', 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') @@ -449,7 +449,7 @@ def link_entrances(world, player): Dungeon_Exits.append(tuple(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)'))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', 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') @@ -499,7 +499,7 @@ def link_entrances(world, player): caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', 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') @@ -567,7 +567,7 @@ def link_entrances(world, player): caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', 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) else: @@ -662,7 +662,7 @@ def link_entrances(world, player): world.ganon_at_pyramid[player] = False # check for Ganon's Tower location - if world.get_entrance('Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', player).connected_region.name != 'Ganons Tower Portal' if not invFlag else 'GT Lobby': + if world.get_entrance('Ganons Tower' if not world.is_atgt_swapped[player] else 'Agahnims Tower', player).connected_region.name != 'Ganons Tower Portal' if not invFlag else 'GT Lobby': world.ganonstower_vanilla[player] = False @@ -1235,7 +1235,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player): connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (not invFlag)) else 'Agahnims Tower', 'Ganons Tower Exit', 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/Rom.py b/Rom.py index 55a1af05..b6046c3f 100644 --- a/Rom.py +++ b/Rom.py @@ -877,8 +877,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x138006, 1) # swap in non-ER Lobby Shuffle Inverted - but only then - if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted') and \ - world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla' and world.shuffle[player] == 'vanilla': + if world.is_atgt_swapped[player] and world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla' and world.shuffle[player] == 'vanilla': aga_portal = world.get_portal('Agahnims Tower', player) gt_portal = world.get_portal('Ganons Tower', player) aga_portal.exit_offset, gt_portal.exit_offset = gt_portal.exit_offset, aga_portal.exit_offset @@ -1275,7 +1274,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # assorted fixes rom.write_byte(0x1800A2, 0x01 if world.fix_fake_world else 0x00) # remain in real dark world when dying in dark world dungeon before killing aga1 rom.write_byte(0x180169, 0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence. - if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): + if world.is_atgt_swapped[player]: rom.write_byte(0x180169, 0x02) # lock aga/ganon tower door with crystals in inverted rom.write_byte(0x180171, 0x01 if world.ganon_at_pyramid[player] else 0x00) # Enable respawning on pyramid after ganon death rom.write_byte(0x180173, 0x01) # Bob is enabled @@ -1287,7 +1286,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] or world.goal[player] == 'trinity' else 0x00) # pre-open Pyramid Hole rom.write_byte(0x18008C, 0x01 if world.crystals_needed_for_gt[player] == 0 else 0x00) # GT pre-opened if crystal requirement is 0 - rom.write_byte(0x18008F, 0x01 if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted') else 0x00) # AT/GT swapped + rom.write_byte(0x18008F, 0x01 if world.is_atgt_swapped[player] else 0x00) # AT/GT swapped rom.write_byte(0xF5D73, 0xF0) # bees are catchable rom.write_byte(0xF5F10, 0xF0) # bees are catchable rom.write_byte(0x180086, 0x00 if world.aga_randomness else 0x01) # set blue ball and ganon warp randomness @@ -2170,7 +2169,7 @@ def write_strings(rom, world, player, team): entrances_to_hint = {} entrances_to_hint.update(InconvenientDungeonEntrances) if world.shuffle_ganon: - if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): + if world.is_atgt_swapped[player]: entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) else: entrances_to_hint.update({'Ganons Tower': 'Ganon\'s Tower'}) @@ -2203,7 +2202,7 @@ 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 (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): + if 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'}) @@ -2524,8 +2523,7 @@ def set_inverted_mode(world, player, rom, inverted_buffer): rom.write_byte(snes_to_pc(0x02D9B3), 0x12) # switch AT and GT - if world.shuffle[player] == 'vanilla' and \ - (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): + if world.shuffle[player] == 'vanilla' and world.is_atgt_swapped[player]: rom.write_byte(0xDBB73 + 0x23, 0x37) rom.write_byte(0xDBB73 + 0x36, 0x24) if world.doorShuffle[player] == 'vanilla' or world.intensity[player] < 3: diff --git a/Rules.py b/Rules.py index 50d808b0..cabe695e 100644 --- a/Rules.py +++ b/Rules.py @@ -854,7 +854,7 @@ def default_rules(world, player): def ow_rules(world, player): - if (0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted'): + if world.is_atgt_swapped[player]: set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) else: set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has_beam_sword(player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle @@ -1524,7 +1524,7 @@ def swordless_rules(world, player): set_rule(world.get_location('Ganon', player), lambda state: state.has('Hammer', player) and state.has_fire_source(player) and state.has('Silver Arrows', player) and state.can_shoot_arrows(player) and state.has_crystals(world.crystals_needed_for_ganon[player], player)) set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has('Hammer', player)) # need to damage ganon to get tiles to drop - if not ((0x03 in world.owswaps[player][0]) == (0x1b in world.owswaps[player][0]) == (world.mode[player] != 'inverted')): + if not world.is_atgt_swapped[player]: set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!) From 7a186e647f8011d0a2f36b2330cb798ce4a6cc6b Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 3 Feb 2022 06:57:56 -0600 Subject: [PATCH 59/73] Simplified AT/GT swap condition check --- EntranceShuffle.py | 16 ++++++++-------- Rom.py | 12 ++++++------ Rules.py | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index eb22b044..46217d2e 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -90,7 +90,7 @@ def link_entrances(world, player): for entrancename, exitname in default_skulldrop_connections: connect_logical(world, entrancename, exitname, player, False) - if world.is_atgt_swapped[player]: + if world.is_atgt_swapped(player): for entrancename, exitname in inverted_default_dungeon_connections: connect_logical(world, entrancename, exitname, player, True) else: @@ -288,7 +288,7 @@ def link_entrances(world, player): caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped[player] else 'Agahnims Tower', 'Ganons Tower Exit', 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') @@ -361,7 +361,7 @@ def link_entrances(world, player): lw_dungeons.append(tuple(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)'))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped[player] else 'Agahnims Tower', 'Ganons Tower Exit', 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') @@ -449,7 +449,7 @@ def link_entrances(world, player): Dungeon_Exits.append(tuple(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)'))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped[player] else 'Agahnims Tower', 'Ganons Tower Exit', 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') @@ -499,7 +499,7 @@ def link_entrances(world, player): caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3))) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped[player] else 'Agahnims Tower', 'Ganons Tower Exit', 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') @@ -567,7 +567,7 @@ def link_entrances(world, player): caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped[player] else 'Agahnims Tower', 'Ganons Tower Exit', 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) else: @@ -662,7 +662,7 @@ def link_entrances(world, player): world.ganon_at_pyramid[player] = False # check for Ganon's Tower location - if world.get_entrance('Ganons Tower' if not world.is_atgt_swapped[player] else 'Agahnims Tower', player).connected_region.name != 'Ganons Tower Portal' if not invFlag else 'GT Lobby': + if world.get_entrance('Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', player).connected_region.name != 'Ganons Tower Portal' if not invFlag else 'GT Lobby': world.ganonstower_vanilla[player] = False @@ -1235,7 +1235,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player): connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower' if not world.is_atgt_swapped[player] else 'Agahnims Tower', 'Ganons Tower Exit', 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/Rom.py b/Rom.py index b6046c3f..a71c1a72 100644 --- a/Rom.py +++ b/Rom.py @@ -877,7 +877,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x138006, 1) # swap in non-ER Lobby Shuffle Inverted - but only then - if world.is_atgt_swapped[player] and world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla' and world.shuffle[player] == 'vanilla': + if world.is_atgt_swapped(player) and world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla' and world.shuffle[player] == 'vanilla': aga_portal = world.get_portal('Agahnims Tower', player) gt_portal = world.get_portal('Ganons Tower', player) aga_portal.exit_offset, gt_portal.exit_offset = gt_portal.exit_offset, aga_portal.exit_offset @@ -1274,7 +1274,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # assorted fixes rom.write_byte(0x1800A2, 0x01 if world.fix_fake_world else 0x00) # remain in real dark world when dying in dark world dungeon before killing aga1 rom.write_byte(0x180169, 0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence. - if world.is_atgt_swapped[player]: + if world.is_atgt_swapped(player): rom.write_byte(0x180169, 0x02) # lock aga/ganon tower door with crystals in inverted rom.write_byte(0x180171, 0x01 if world.ganon_at_pyramid[player] else 0x00) # Enable respawning on pyramid after ganon death rom.write_byte(0x180173, 0x01) # Bob is enabled @@ -1286,7 +1286,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] or world.goal[player] == 'trinity' else 0x00) # pre-open Pyramid Hole rom.write_byte(0x18008C, 0x01 if world.crystals_needed_for_gt[player] == 0 else 0x00) # GT pre-opened if crystal requirement is 0 - rom.write_byte(0x18008F, 0x01 if world.is_atgt_swapped[player] else 0x00) # AT/GT swapped + rom.write_byte(0x18008F, 0x01 if world.is_atgt_swapped(player) else 0x00) # AT/GT swapped rom.write_byte(0xF5D73, 0xF0) # bees are catchable rom.write_byte(0xF5F10, 0xF0) # bees are catchable rom.write_byte(0x180086, 0x00 if world.aga_randomness else 0x01) # set blue ball and ganon warp randomness @@ -2169,7 +2169,7 @@ def write_strings(rom, world, player, team): entrances_to_hint = {} entrances_to_hint.update(InconvenientDungeonEntrances) if world.shuffle_ganon: - if world.is_atgt_swapped[player]: + if world.is_atgt_swapped(player): entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) else: entrances_to_hint.update({'Ganons Tower': 'Ganon\'s Tower'}) @@ -2202,7 +2202,7 @@ 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.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'}) @@ -2523,7 +2523,7 @@ def set_inverted_mode(world, player, rom, inverted_buffer): rom.write_byte(snes_to_pc(0x02D9B3), 0x12) # switch AT and GT - if world.shuffle[player] == 'vanilla' and world.is_atgt_swapped[player]: + if world.shuffle[player] == 'vanilla' and world.is_atgt_swapped(player): rom.write_byte(0xDBB73 + 0x23, 0x37) rom.write_byte(0xDBB73 + 0x36, 0x24) if world.doorShuffle[player] == 'vanilla' or world.intensity[player] < 3: diff --git a/Rules.py b/Rules.py index cabe695e..7d3227e8 100644 --- a/Rules.py +++ b/Rules.py @@ -854,7 +854,7 @@ def default_rules(world, player): def ow_rules(world, player): - if world.is_atgt_swapped[player]: + if world.is_atgt_swapped(player): set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) else: set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has_beam_sword(player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle @@ -1524,7 +1524,7 @@ def swordless_rules(world, player): set_rule(world.get_location('Ganon', player), lambda state: state.has('Hammer', player) and state.has_fire_source(player) and state.has('Silver Arrows', player) and state.can_shoot_arrows(player) and state.has_crystals(world.crystals_needed_for_ganon[player], player)) set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has('Hammer', player)) # need to damage ganon to get tiles to drop - if not world.is_atgt_swapped[player]: + if not world.is_atgt_swapped(player): set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!) From 08a8d9223cbe9af6e0bea2a5e6b19ed972287740 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 3 Feb 2022 06:59:24 -0600 Subject: [PATCH 60/73] Version bump 0.2.5.3 --- CHANGELOG.md | 6 ++++++ OverworldShuffle.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd5f3cb1..2ef9d2a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +### 0.2.5.3 +- Changed AT/GT Swap to favor vanilla, only swapping if GT entrance is the only choice in starting world +- Fixed issue with Links House not swapping in OW Mixed +- Added Flute Spots to spoiler log +- Fixed issue with Light Hype Fairy excluded from bombable door list + ### 0.2.5.1 - Fixed missing rule for Inverted VoO Portal access diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 4328101f..e535366f 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -5,7 +5,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl from Regions import mark_dark_world_regions, mark_light_world_regions from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel -__version__ = '0.2.5.2-u' +__version__ = '0.2.5.3-u' def link_overworld(world, player): # setup mandatory connections From 9263c80cce3a788d3f81ae465e0ada4bfb89d8c1 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 4 Feb 2022 06:10:57 -0600 Subject: [PATCH 61/73] Merged in Upstream ER changes -Fixed Witch invisible item bug -Added new font changes, not enabled yet --- Rom.py | 2 +- data/base2current.bps | Bin 87439 -> 87473 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index a71c1a72..a4c2cb04 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '9ff49ef63fdddeb32de09646bd459bf8' +RANDOMIZERBASEHASH = 'e4d9784d6bb96d86193dfca4d4675838' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index d588f66b3b9c808ccf8ec17e3a8522db9a3095ca..85f47b5253770a30102cdd95017a3a39c9275660 100644 GIT binary patch delta 10124 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 QKU@V}ds_Bk`~1KEKWYvGF8}}l delta 9835 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 CgKSR# From a7a148ed1807effd1b24ce534bb50db9804c1827 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 4 Feb 2022 06:47:33 -0600 Subject: [PATCH 62/73] Adding 'O' to ROM header to indicate a seed from OWR branch --- Rom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index a4c2cb04..d34b65de 100644 --- a/Rom.py +++ b/Rom.py @@ -1674,7 +1674,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): from Main import __version__ seedstring = f'{world.seed:09}' if isinstance(world.seed, int) else world.seed # todo: change to DR when Enemizer is okay with DR - rom.name = bytearray(f'ER{__version__.split("-")[0].replace(".","")[0:3]}_{team+1}_{player}_{seedstring}\0', 'utf8')[:21] + rom.name = bytearray(f'ER{__version__.split("-")[0].replace(".","")[0:3]}_{team+1}_{player}_{seedstring}O\0', 'utf8')[:21] rom.name.extend([0] * (21 - len(rom.name))) rom.write_bytes(0x7FC0, rom.name) From 90484ac6c4b5f97d18666d607623cd1c4c719604 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 4 Feb 2022 16:08:12 -0600 Subject: [PATCH 63/73] Enabled new text font --- Rom.py | 2 +- data/base2current.bps | Bin 87473 -> 91685 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index d34b65de..6e5a2dfb 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'e4d9784d6bb96d86193dfca4d4675838' +RANDOMIZERBASEHASH = '87b41e582793f55739afa43e811b2919' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 85f47b5253770a30102cdd95017a3a39c9275660..c8e8cbb4c4d9264203601dd8adf818b9abb45977 100644 GIT binary patch delta 4623 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 a)Z`TozaK@vvQ=b>WR~r<#Q$@X>i+?&hPPh; delta 356 zcmZ2_hIQj=)(x(VEXP(_hHds_oF?da>e&L7?#ceqlPvmsm7d&NkkAUI0vf>7gUvq0 zlR_HSFF3LLok`dH1r;;;8JkpkCp$MWG)(U1Xqv1sW3#t#_f?U`jPi;$si=?QvYkcw zosBNjl&u;!hrbpPd(@8)phP$m*`zF3-%kg^6>Uf?$Jk zL$Nr^^gFDKHq4bujoYQ!7!BCP#3V%;rm8V8Fe)(4D|B48yryxww#km^@w|+Z%x5OA znO@J!n5v%Hx>6sg#FPOD7|kYgwa=2{S<%X9*xx>t(SXs2(R_06Y|e^3(}nmLd$Dv5$*~TYMsG>C|GOiPan(+g&6XB{-Nh**620!yE#s@Y-nd}SKI>t0hoZ> From d3bf6883b7938bfe0ad62113b9e4f554d83952ce Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 6 Feb 2022 07:41:06 -0600 Subject: [PATCH 64/73] Enabled new font + lowercase hint text updates --- Items.py | 56 +++++++++++++++++++++--------------------- Regions.py | 36 +++++++++++++-------------- Rom.py | 6 ++--- Text.py | 29 +++++++++++++++------- data/base2current.bps | Bin 91685 -> 91683 bytes 5 files changed, 69 insertions(+), 58 deletions(-) diff --git a/Items.py b/Items.py index fd7fa0f9..6d7f9627 100644 --- a/Items.py +++ b/Items.py @@ -27,24 +27,24 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche 'Progressive Bow': (True, False, None, 0x64, 150, 'You have\nchosen the\narcher class.', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'a Bow'), 'Progressive Bow (Alt)': (True, False, None, 0x65, 150, 'You have\nchosen the\narcher class.', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'a Bow'), 'Book of Mudora': (True, False, None, 0x1D, 150, 'This is a\nparadox?!', 'and the story book', 'the scholarly kid', 'moon runes for sale', 'drugs for literacy', 'book-worm boy can read again', 'the Book'), - 'Hammer': (True, False, None, 0x09, 250, 'stop\nhammer time!', 'and m c hammer', 'hammer-smashing kid', 'm c hammer for sale', 'stop... hammer time', 'stop, hammer time', 'the hammer'), + 'Hammer': (True, False, None, 0x09, 250, 'stop\nhammer time!', 'and m c hammer', 'hammer-smashing kid', 'm c hammer for sale', 'stop... hammer time', 'stop, hammer time', 'the Hammer'), 'Hookshot': (True, False, None, 0x0A, 250, 'BOING!!!\nBOING!!!\nBOING!!!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'the Hookshot'), 'Magic Mirror': (True, False, None, 0x1A, 250, 'Isn\'t your\nreflection so\npretty?', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'the Mirror'), 'Ocarina': (True, False, None, 0x14, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the Flute'), 'Ocarina (Activated)': (True, False, None, 0x4A, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the Flute'), 'Pegasus Boots': (True, False, None, 0x4B, 250, 'Gotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'the Boots'), - 'Power Glove': (True, False, None, 0x1B, 100, 'Now you can\nlift weak\nstuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the glove'), - 'Cape': (True, False, None, 0x19, 50, 'Wear this to\nbecome\ninvisible!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the cape'), - 'Mushroom': (True, False, None, 0x29, 50, 'I\'m a fun guy!\n\nI\'m a funghi!', 'and the legal drugs', 'the drug-dealing kid', 'legal drugs for sale', 'shroom swap', 'shroom boy sells drugs again', 'the mushroom'), - 'Shovel': (True, False, None, 0x13, 50, 'Can\n You\n Dig it?', 'and the spade', 'archaeologist kid', 'dirt spade for sale', 'can you dig it', 'shovel boy digs again', 'the shovel'), - 'Lamp': (True, False, None, 0x12, 150, 'Baby, baby,\nbaby.\nLight my way!', 'and the flashlight', 'light-shining kid', 'flashlight for sale', 'fungus for illumination', 'illuminated boy can see again', 'the lamp'), - 'Magic Powder': (True, False, None, 0x0D, 50, 'you can turn\nanti-faeries\ninto faeries', 'and the magic sack', 'the sack-holding kid', 'magic sack for sale', 'the witch and assistant', 'magic boy plays marbles again', 'the powder'), - 'Moon Pearl': (True, False, None, 0x1F, 200, ' Bunny Link\n be\n gone!', 'and the jaw breaker', 'fortune-telling kid', 'lunar orb for sale', 'shrooms for moon rock', 'moon boy plays ball again', 'the moon pearl'), - 'Cane of Somaria': (True, False, None, 0x15, 250, 'I make blocks\nto hold down\nswitches!', 'and the red blocks', 'the block-making kid', 'block stick for sale', 'block stick for trade', 'cane boy makes blocks again', 'the red cane'), - 'Fire Rod': (True, False, None, 0x07, 250, 'I\'m the hot\nrod. I make\nthings burn!', 'and the flamethrower', 'fire-starting kid', 'rage rod for sale', 'fungus for rage-rod', 'firestarter boy burns again', 'the fire rod'), + 'Power Glove': (True, False, None, 0x1B, 100, 'Now you can\nlift weak\nstuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the Glove'), + 'Cape': (True, False, None, 0x19, 50, 'Wear this to\nbecome\ninvisible!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the Cape'), + 'Mushroom': (True, False, None, 0x29, 50, 'I\'m a fun guy!\n\nI\'m a funghi!', 'and the legal drugs', 'the drug-dealing kid', 'legal drugs for sale', 'shroom swap', 'shroom boy sells drugs again', 'the Mushroom'), + 'Shovel': (True, False, None, 0x13, 50, 'Can\n You\n Dig it?', 'and the spade', 'archaeologist kid', 'dirt spade for sale', 'can you dig it', 'shovel boy digs again', 'the Shovel'), + 'Lamp': (True, False, None, 0x12, 150, 'Baby, baby,\nbaby.\nLight my way!', 'and the flashlight', 'light-shining kid', 'flashlight for sale', 'fungus for illumination', 'illuminated boy can see again', 'the Lamp'), + 'Magic Powder': (True, False, None, 0x0D, 50, 'you can turn\nanti-faeries\ninto faeries', 'and the magic sack', 'the sack-holding kid', 'magic sack for sale', 'the witch and assistant', 'magic boy plays marbles again', 'the Powder'), + 'Moon Pearl': (True, False, None, 0x1F, 200, ' Bunny Link\n be\n gone!', 'and the jaw breaker', 'fortune-telling kid', 'lunar orb for sale', 'shrooms for moon rock', 'moon boy plays ball again', 'the Moon Pearl'), + 'Cane of Somaria': (True, False, None, 0x15, 250, 'I make blocks\nto hold down\nswitches!', 'and the red blocks', 'the block-making kid', 'block stick for sale', 'block stick for trade', 'cane boy makes blocks again', 'the Red Cane'), + 'Fire Rod': (True, False, None, 0x07, 250, 'I\'m the hot\nrod. I make\nthings burn!', 'and the flamethrower', 'fire-starting kid', 'rage rod for sale', 'fungus for rage-rod', 'firestarter boy burns again', 'the Fire Rod'), 'Flippers': (True, False, None, 0x1E, 250, 'fancy a swim?', 'and the toewebs', 'the swimming kid', 'finger webs for sale', 'shrooms let you swim', 'swimming boy swims again', 'the flippers'), - 'Ice Rod': (True, False, None, 0x08, 250, 'I\'m the cold\nrod. I make\nthings freeze!', 'and the freeze ray', 'the ice-bending kid', 'freeze ray for sale', 'fungus for ice-rod', 'ice-cube boy freezes again', 'the ice rod'), - 'Titans Mitts': (True, False, None, 0x1C, 200, 'Now you can\nlift heavy\nstuff!', 'and the golden glove', 'body-building kid', 'carry glove for sale', 'fungus for bling-gloves', 'body-building boy has gold again', 'the mitts'), + 'Ice Rod': (True, False, None, 0x08, 250, 'I\'m the cold\nrod. I make\nthings freeze!', 'and the freeze ray', 'the ice-bending kid', 'freeze ray for sale', 'fungus for ice-rod', 'ice-cube boy freezes again', 'the Ice Rod'), + 'Titans Mitts': (True, False, None, 0x1C, 200, 'Now you can\nlift heavy\nstuff!', 'and the golden glove', 'body-building kid', 'carry glove for sale', 'fungus for bling-gloves', 'body-building boy has gold again', 'the Mitts'), 'Bombos': (True, False, None, 0x0F, 100, 'Burn, baby,\nburn! Fear my\nring of fire!', 'and the swirly coin', 'coin-collecting kid', 'swirly coin for sale', 'shrooms for swirly-coin', 'medallion boy melts room again', 'Bombos'), 'Ether': (True, False, None, 0x10, 100, 'This magic\ncoin freezes\neverything!', 'and the bolt coin', 'coin-collecting kid', 'bolt coin for sale', 'shrooms for bolt-coin', 'medallion boy sees floor again', 'Ether'), 'Quake': (True, False, None, 0x11, 100, 'Maxing out the\nRichter scale\nis what I do!', 'and the wavy coin', 'coin-collecting kid', 'wavy coin for sale', 'shrooms for wavy-coin', 'medallion boy shakes dirt again', 'Quake'), @@ -57,11 +57,11 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche 'Bottle (Good Bee)': (True, False, None, 0x48, 60, 'I will sting your foes a whole lot!', 'and the sparkle sting', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has beetor again', 'a Bottle'), 'Master Sword': (True, False, 'Sword', 0x50, 100, 'I beat barries and pigs alike', 'and the master sword', 'sword-wielding kid', 'glow sword for sale', 'fungus for blue slasher', 'sword boy fights again', 'the Master Sword'), 'Tempered Sword': (True, False, 'Sword', 0x02, 150, 'I stole the\nblacksmith\'s\njob!', 'the tempered sword', 'sword-wielding kid', 'flame sword for sale', 'fungus for red slasher', 'sword boy fights again', 'the Tempered Sword'), - 'Fighter Sword': (True, False, 'Sword', 0x49, 50, 'A pathetic\nsword rests\nhere!', 'the tiny sword', 'sword-wielding kid', 'tiny sword for sale', 'fungus for tiny slasher', 'sword boy fights again', 'the small sword'), + 'Fighter Sword': (True, False, 'Sword', 0x49, 50, 'A pathetic\nsword rests\nhere!', 'the tiny sword', 'sword-wielding kid', 'tiny sword for sale', 'fungus for tiny slasher', 'sword boy fights again', 'the Fighter Sword'), 'Golden Sword': (True, False, 'Sword', 0x03, 200, 'The butter\nsword rests\nhere!', 'and the butter sword', 'sword-wielding kid', 'butter for sale', 'cap churned to butter', 'sword boy fights again', 'the Golden Sword'), - 'Progressive Sword': (True, False, 'Sword', 0x5E, 150, 'a better copy\nof your sword\nfor your time', 'the unknown sword', 'sword-wielding kid', 'sword for sale', 'fungus for some slasher', 'sword boy fights again', 'a sword'), - 'Progressive Glove': (True, False, None, 0x61, 150, 'a way to lift\nheavier things', 'and the lift upgrade', 'body-building kid', 'some glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'a glove'), - 'Silver Arrows': (True, False, None, 0x58, 100, 'Do you fancy\nsilver tipped\narrows?', 'and the ganonsbane', 'ganon-killing kid', 'ganon doom for sale', 'fungus for pork', 'archer boy shines again', 'the silver arrows'), + 'Progressive Sword': (True, False, 'Sword', 0x5E, 150, 'a better copy\nof your sword\nfor your time', 'the unknown sword', 'sword-wielding kid', 'sword for sale', 'fungus for some slasher', 'sword boy fights again', 'a Sword'), + 'Progressive Glove': (True, False, None, 0x61, 150, 'a way to lift\nheavier things', 'and the lift upgrade', 'body-building kid', 'some glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'a Glove'), + 'Silver Arrows': (True, False, None, 0x58, 100, 'Do you fancy\nsilver tipped\narrows?', 'and the ganonsbane', 'ganon-killing kid', 'ganon doom for sale', 'fungus for pork', 'archer boy shines again', 'the Silver Arrows'), 'Green Pendant': (True, False, 'Crystal', [0x04, 0x38, 0x62, 0x00, 0x69, 0x01], 999, None, None, None, None, None, None, None), 'Blue Pendant': (True, False, 'Crystal', [0x02, 0x34, 0x60, 0x00, 0x69, 0x02], 999, None, None, None, None, None, None, None), 'Red Pendant': (True, False, 'Crystal', [0x01, 0x32, 0x60, 0x00, 0x69, 0x03], 999, None, None, None, None, None, None, None), @@ -84,17 +84,17 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche 'Bombs (10)': (False, False, None, 0x31, 50, 'I make things\ngo BOOM! Ten\ntimes!', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'ten bombs'), 'Bomb Upgrade (+10)': (False, False, None, 0x52, 100, 'increase bomb\nstorage, low\nlow price', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'), 'Bomb Upgrade (+5)': (False, False, None, 0x51, 100, 'increase bomb\nstorage, low\nlow price', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'), - 'Blue Mail': (False, True, None, 0x22, 50, 'Now you\'re a\nblue elf!', 'and the banana hat', 'the protected kid', 'banana hat for sale', 'the clothing store', 'tailor boy banana hatted again', 'the blue mail'), - 'Red Mail': (False, True, None, 0x23, 100, 'Now you\'re a\nred elf!', 'and the eggplant hat', 'well-protected kid', 'purple hat for sale', 'the nice clothing store', 'tailor boy fears nothing again', 'the red mail'), + 'Blue Mail': (False, True, None, 0x22, 50, 'Now you\'re a\nblue elf!', 'and the banana hat', 'the protected kid', 'banana hat for sale', 'the clothing store', 'tailor boy banana hatted again', 'the Blue Mail'), + 'Red Mail': (False, True, None, 0x23, 100, 'Now you\'re a\nred elf!', 'and the eggplant hat', 'well-protected kid', 'purple hat for sale', 'the nice clothing store', 'tailor boy fears nothing again', 'the Red Mail'), 'Progressive Armor': (False, True, None, 0x60, 50, 'time for a\nchange of\nclothes?', 'and the unknown hat', 'the protected kid', 'new hat for sale', 'the clothing store', 'tailor boy has threads again', 'some armor'), - 'Blue Boomerang': (True, False, None, 0x0C, 50, 'No matter what\nyou do, blue\nreturns to you', 'and the bluemarang', 'the bat-throwing kid', 'bent stick for sale', 'fungus for puma-stick', 'throwing boy plays fetch again', 'the blue boomerang'), - 'Red Boomerang': (True, False, None, 0x2A, 50, 'No matter what\nyou do, red\nreturns to you', 'and the badmarang', 'the bat-throwing kid', 'air foil for sale', 'fungus for return-stick', 'magical boy plays fetch again', 'the red boomerang'), - 'Blue Shield': (False, True, None, 0x04, 50, 'Now you can\ndefend against\npebbles!', 'and the stone blocker', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'the blue shield'), - 'Red Shield': (False, True, None, 0x05, 500, 'Now you can\ndefend against\nfireballs!', 'and the shot blocker', 'shield-wielding kid', 'fire shield for sale', 'fungus for fire shield', 'shield boy defends again', 'the red shield'), - 'Mirror Shield': (True, False, None, 0x06, 200, 'Now you can\ndefend against\nlasers!', 'and the laser blocker', 'shield-wielding kid', 'face shield for sale', 'fungus for face shield', 'shield boy defends again', 'the mirror shield'), + 'Blue Boomerang': (True, False, None, 0x0C, 50, 'No matter what\nyou do, blue\nreturns to you', 'and the bluemarang', 'the bat-throwing kid', 'bent stick for sale', 'fungus for puma-stick', 'throwing boy plays fetch again', 'the Blue Boomerang'), + 'Red Boomerang': (True, False, None, 0x2A, 50, 'No matter what\nyou do, red\nreturns to you', 'and the badmarang', 'the bat-throwing kid', 'air foil for sale', 'fungus for return-stick', 'magical boy plays fetch again', 'the Red Boomerang'), + 'Blue Shield': (False, True, None, 0x04, 50, 'Now you can\ndefend against\npebbles!', 'and the stone blocker', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'the Blue Shield'), + 'Red Shield': (False, True, None, 0x05, 500, 'Now you can\ndefend against\nfireballs!', 'and the shot blocker', 'shield-wielding kid', 'fire shield for sale', 'fungus for fire shield', 'shield boy defends again', 'the Red Shield'), + 'Mirror Shield': (True, False, None, 0x06, 200, 'Now you can\ndefend against\nlasers!', 'and the laser blocker', 'shield-wielding kid', 'face shield for sale', 'fungus for face shield', 'shield boy defends again', 'the Mirror Shield'), 'Progressive Shield': (True, False, None, 0x5F, 50, 'have a better\nblocker in\nfront of you', 'and the new shield', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'a shield'), - 'Bug Catching Net': (True, False, None, 0x21, 50, 'Let\'s catch\nsome bees and\nfaeries!', 'and the bee catcher', 'the bug-catching kid', 'stick web for sale', 'fungus for butterflies', 'wrong boy catches bees again', 'the bug net'), - 'Cane of Byrna': (True, False, None, 0x18, 50, 'Use this to\nbecome\ninvincible!', 'and the bad cane', 'the spark-making kid', 'spark stick for sale', 'spark-stick for trade', 'cane boy encircles again', 'the blue cane'), + 'Bug Catching Net': (True, False, None, 0x21, 50, 'Let\'s catch\nsome bees and\nfaeries!', 'and the bee catcher', 'the bug-catching kid', 'stick web for sale', 'fungus for butterflies', 'wrong boy catches bees again', 'the Bug Net'), + 'Cane of Byrna': (True, False, None, 0x18, 50, 'Use this to\nbecome\ninvincible!', 'and the bad cane', 'the spark-making kid', 'spark stick for sale', 'spark-stick for trade', 'cane boy encircles again', 'the Blue Cane'), 'Boss Heart Container': (False, False, None, 0x3E, 40, 'Maximum health\nincreased!\nYeah!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'a heart'), 'Sanctuary Heart Container': (False, False, None, 0x3F, 50, 'Maximum health\nincreased!\nYeah!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'a heart'), 'Piece of Heart': (False, False, None, 0x17, 10, 'Just a little\npiece of love!', 'and the broken heart', 'the life-giving kid', 'little love for sale', 'fungus for life', 'life boy feels some love again', 'a heart piece'), @@ -110,8 +110,8 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche 'Green Clock': (False, True, None, 0x5D, 200, 'a lot of time', 'the emerald clock', 'the emerald-time kid', 'green time for sale', 'for emerald time', 'moment boy adjusts time again', 'a red clock'), 'Single RNG': (False, True, None, 0x62, 300, 'something you don\'t yet have', None, None, None, None, 'unknown boy somethings again', 'a new mystery'), 'Multi RNG': (False, True, None, 0x63, 100, 'something you may already have', None, None, None, None, 'unknown boy somethings again', 'a total mystery'), - 'Magic Upgrade (1/2)': (True, False, None, 0x4E, 50, 'Your magic\npower has been\ndoubled!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'half magic'), # can be required to beat mothula in an open seed in very very rare circumstance - 'Magic Upgrade (1/4)': (True, False, None, 0x4F, 100, 'Your magic\npower has been\nquadrupled!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'quarter magic'), # can be required to beat mothula in an open seed in very very rare circumstance + 'Magic Upgrade (1/2)': (True, False, None, 0x4E, 50, 'Your magic\npower has been\ndoubled!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Half magic'), # can be required to beat mothula in an open seed in very very rare circumstance + 'Magic Upgrade (1/4)': (True, False, None, 0x4F, 100, 'Your magic\npower has been\nquadrupled!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Quarter magic'), # can be required to beat mothula in an open seed in very very rare circumstance 'Small Key (Eastern Palace)': (False, False, 'SmallKey', 0xA2, 40, 'A small key to Armos Knights', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Eastern Palace'), 'Big Key (Eastern Palace)': (False, False, 'BigKey', 0x9D, 60, 'A big key to Armos Knights', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Eastern Palace'), 'Compass (Eastern Palace)': (False, True, 'Compass', 0x8D, 10, 'Now you can find the Armos Knights!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Eastern Palace'), @@ -162,7 +162,7 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche 'Map (Turtle Rock)': (False, True, 'Map', 0x73, 20, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Turtle Rock'), 'Small Key (Ganons Tower)': (False, False, 'SmallKey', 0xAD, 40, 'A small key to the evil tower', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Ganon\'s Tower'), 'Big Key (Ganons Tower)': (False, False, 'BigKey', 0x92, 60, 'A big key to the evil tower', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Ganon\'s Tower'), - 'Compass (Ganons Tower)': (False, True, 'Compass', 0x82, 10, 'Now you can find Agahnim!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a comapss to Ganon\'s Tower'), + 'Compass (Ganons Tower)': (False, True, 'Compass', 0x82, 10, 'Now you can find Agahnim!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Ganon\'s Tower'), 'Map (Ganons Tower)': (False, True, 'Map', 0x72, 10, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Ganon\'s Tower'), 'Small Key (Universal)': (False, True, None, 0xAF, 100, 'A small key for any door', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key'), 'Nothing': (False, False, None, 0x5A, 1, 'Some Hot Air', 'and the Nothing', 'the zen kid', 'outright theft', 'shroom theft', 'empty boy is bored again', 'nothing'), diff --git a/Regions.py b/Regions.py index f94599a8..98548c9d 100644 --- a/Regions.py +++ b/Regions.py @@ -1242,8 +1242,8 @@ key_drop_data = { 'Swamp Palace - Waterway Pot Key': [0x140009, 0x14000a, 'in Swamp Palace', 'Small Key (Swamp Palace)'], 'Skull Woods - West Lobby Pot Key': [0x14002d, 0x14002e, 'in Skull Woods', 'Small Key (Skull Woods)'], 'Skull Woods - Spike Corner Key Drop': [0x14001b, 0x14001c, 'near Mothula', 'Small Key (Skull Woods)'], - "Thieves' Town - Hallway Pot Key": [0x14005d, 0x14005e, "in Thieves' Town", 'Small Key (Thieves Town)'], - "Thieves' Town - Spike Switch Pot Key": [0x14004e, 0x14004f, "in Thieves' Town", 'Small Key (Thieves Town)'], + "Thieves' Town - Hallway Pot Key": [0x14005d, 0x14005e, "in Thieves Town", 'Small Key (Thieves Town)'], + "Thieves' Town - Spike Switch Pot Key": [0x14004e, 0x14004f, "in Thieves Town", 'Small Key (Thieves Town)'], 'Ice Palace - Jelly Key Drop': [0x140003, 0x140004, 'in Ice Palace', 'Small Key (Ice Palace)'], 'Ice Palace - Conveyor Key Drop': [0x140021, 0x140022, 'in Ice Palace', 'Small Key (Ice Palace)'], 'Ice Palace - Hammer Block Key Drop': [0x140024, 0x140025, 'in Ice Palace', 'Small Key (Ice Palace)'], @@ -1306,10 +1306,10 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'), 'Kakariko Well - Middle': (0xea94, 0x186268, False, 'in a well'), 'Kakariko Well - Right': (0xea97, 0x18626b, False, 'in a well'), 'Kakariko Well - Bottom': (0xea9a, 0x18626e, False, 'in a well'), - 'Blacksmith': (0x18002a, 0x186366, False, 'with the smith'), - 'Magic Bat': (0x180015, 0x18635e, False, 'with the bat'), + 'Blacksmith': (0x18002a, 0x186366, False, 'with the Smith'), + 'Magic Bat': (0x180015, 0x18635e, False, 'with the Bat'), 'Sick Kid': (0x339cf, 0x186367, False, 'with the sick'), - 'Hobo': (0x33e7d, 0x186368, False, 'with the hobo'), + 'Hobo': (0x33e7d, 0x186368, False, 'with the Hobo'), 'Lost Woods Hideout': (0x180000, 0x186348, False, 'near a thief'), 'Lumberjack Tree': (0x180001, 0x186349, False, 'in a hole'), 'Cave 45': (0x180003, 0x18634b, False, 'alone in a cave'), @@ -1339,7 +1339,7 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'), 'Eastern Palace - Big Key Chest': (0xe9b9, 0x18618d, False, 'in Eastern Palace'), 'Eastern Palace - Map Chest': (0xe9f5, 0x1861c9, False, 'in Eastern Palace'), 'Eastern Palace - Boss': (0x180150, 0x18633e, False, 'with the Armos'), - 'Master Sword Pedestal': (0x289b0, 0x186369, False, 'at the pedestal'), + 'Master Sword Pedestal': (0x289b0, 0x186369, False, 'at the Pedestal'), 'Hyrule Castle - Boomerang Chest': (0xe974, 0x186148, False, 'in Hyrule Castle'), 'Hyrule Castle - Map Chest': (0xeb0c, 0x1862e0, False, 'in Hyrule Castle'), "Hyrule Castle - Zelda's Chest": (0xeb09, 0x1862dd, False, 'in Hyrule Castle'), @@ -1350,7 +1350,7 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'), 'Sanctuary': (0xea79, 0x18624d, False, 'in Sanctuary'), 'Castle Tower - Room 03': (0xeab5, 0x186289, False, 'in Castle Tower'), 'Castle Tower - Dark Maze': (0xeab2, 0x186286, False, 'in Castle Tower'), - 'Old Man': (0xf69fa, 0x186364, False, 'with the old man'), + 'Old Man': (0xf69fa, 0x186364, False, 'with the Old Man'), 'Spectacle Rock Cave': (0x180002, 0x18634a, False, 'alone in a cave'), 'Paradox Cave Lower - Far Left': (0xeb2a, 0x1862fe, False, 'in a cave with seven chests'), 'Paradox Cave Lower - Left': (0xeb2d, 0x186301, False, 'in a cave with seven chests'), @@ -1359,7 +1359,7 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'), 'Paradox Cave Lower - Middle': (0xeb36, 0x18630a, False, 'in a cave with seven chests'), 'Paradox Cave Upper - Left': (0xeb39, 0x18630d, False, 'in a cave with seven chests'), 'Paradox Cave Upper - Right': (0xeb3c, 0x186310, False, 'in a cave with seven chests'), - 'Spiral Cave': (0xe9bf, 0x186193, False, 'in spiral cave'), + 'Spiral Cave': (0xe9bf, 0x186193, False, 'in Spiral Cave'), 'Ether Tablet': (0x180016, 0x18633b, False, 'at a monolith'), 'Spectacle Rock': (0x180140, 0x18634f, False, 'atop a rock'), 'Tower of Hera - Basement Cage': (0x180162, 0x18633a, False, 'in Tower of Hera'), @@ -1368,9 +1368,9 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'), 'Tower of Hera - Compass Chest': (0xe9fb, 0x1861cf, False, 'in Tower of Hera'), 'Tower of Hera - Big Chest': (0xe9f8, 0x1861cc, False, 'in Tower of Hera'), 'Tower of Hera - Boss': (0x180152, 0x186340, False, 'with Moldorm'), - 'Pyramid': (0x180147, 0x186356, False, 'on the pyramid'), + 'Pyramid': (0x180147, 0x186356, False, 'on the Pyramid'), 'Catfish': (0xee185, 0x186361, False, 'with a catfish'), - 'Stumpy': (0x330c7, 0x18636a, False, 'with tree boy'), + 'Stumpy': (0x330c7, 0x18636a, False, 'with Tree Boy'), 'Digging Game': (0x180148, 0x186357, False, 'underground'), 'Bombos Tablet': (0x180017, 0x18633c, False, 'at a monolith'), 'Hype Cave - Top': (0xeb1e, 0x1862f2, False, 'near a bat-like man'), @@ -1406,13 +1406,13 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'), 'Swamp Palace - Flooded Room - Right': (0xeaac, 0x186280, False, 'in Swamp Palace'), 'Swamp Palace - Waterfall Room': (0xeaaf, 0x186283, False, 'in Swamp Palace'), 'Swamp Palace - Boss': (0x180154, 0x186342, False, 'with Arrghus'), - "Thieves' Town - Big Key Chest": (0xea04, 0x1861d8, False, "in Thieves' Town"), - "Thieves' Town - Map Chest": (0xea01, 0x1861d5, False, "in Thieves' Town"), - "Thieves' Town - Compass Chest": (0xea07, 0x1861db, False, "in Thieves' Town"), - "Thieves' Town - Ambush Chest": (0xea0a, 0x1861de, False, "in Thieves' Town"), - "Thieves' Town - Attic": (0xea0d, 0x1861e1, False, "in Thieves' Town"), - "Thieves' Town - Big Chest": (0xea10, 0x1861e4, False, "in Thieves' Town"), - "Thieves' Town - Blind's Cell": (0xea13, 0x1861e7, False, "in Thieves' Town"), + "Thieves' Town - Big Key Chest": (0xea04, 0x1861d8, False, "in Thieves Town"), + "Thieves' Town - Map Chest": (0xea01, 0x1861d5, False, "in Thieves Town"), + "Thieves' Town - Compass Chest": (0xea07, 0x1861db, False, "in Thieves Town"), + "Thieves' Town - Ambush Chest": (0xea0a, 0x1861de, False, "in Thieves Town"), + "Thieves' Town - Attic": (0xea0d, 0x1861e1, False, "in Thieves Town"), + "Thieves' Town - Big Chest": (0xea10, 0x1861e4, False, "in Thieves Town"), + "Thieves' Town - Blind's Cell": (0xea13, 0x1861e7, False, "in Thieves Town"), "Thieves' Town - Boss": (0x180156, 0x186344, False, 'with Blind'), 'Skull Woods - Compass Chest': (0xe992, 0x186166, False, 'in Skull Woods'), 'Skull Woods - Map Chest': (0xe99b, 0x18616f, False, 'in Skull Woods'), @@ -1515,7 +1515,7 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'), 'Tower of Hera - Prize': ([0x120A5, 0x53F0A, 0x53F0B, 0x18005A, 0x18007A, 0xC706], None, True, 'Tower of Hera'), 'Palace of Darkness - Prize': ([0x120A1, 0x53F00, 0x53F01, 0x180056, 0x18007D, 0xC702], None, True, 'Palace of Darkness'), 'Swamp Palace - Prize': ([0x120A0, 0x53F6C, 0x53F6D, 0x180055, 0x180071, 0xC701], None, True, 'Swamp Palace'), - 'Thieves\' Town - Prize': ([0x120A6, 0x53F36, 0x53F37, 0x18005B, 0x180077, 0xC707], None, True, 'Thieves\' Town'), + 'Thieves\' Town - Prize': ([0x120A6, 0x53F36, 0x53F37, 0x18005B, 0x180077, 0xC707], None, True, 'Thieves Town'), 'Skull Woods - Prize': ([0x120A3, 0x53F12, 0x53F13, 0x180058, 0x18007B, 0xC704], None, True, 'Skull Woods'), 'Ice Palace - Prize': ([0x120A4, 0x53F5A, 0x53F5B, 0x180059, 0x180073, 0xC705], None, True, 'Ice Palace'), 'Misery Mire - Prize': ([0x120A2, 0x53F48, 0x53F49, 0x180057, 0x180075, 0xC703], None, True, 'Misery Mire'), diff --git a/Rom.py b/Rom.py index 6e5a2dfb..3d910b80 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '87b41e582793f55739afa43e811b2919' +RANDOMIZERBASEHASH = '57d36048e54cd5a281f1dbf66f2bc9c2' class JsonRom(object): @@ -2439,8 +2439,8 @@ def write_strings(rom, world, player, team): # inverted spawn menu changes if world.mode[player] == 'inverted': - tt['menu_start_2'] = "{MENU}\n{SPEED0}\n≥@'s house\n Dark Chapel\n{CHOICE3}" - tt['menu_start_3'] = "{MENU}\n{SPEED0}\n≥@'s house\n Dark Chapel\n Mountain Cave\n{CHOICE2}" + tt['menu_start_2'] = "{MENU}\n{SPEED0}\n≥@'s House\n Dark Chapel\n{CHOICE3}" + tt['menu_start_3'] = "{MENU}\n{SPEED0}\n≥@'s House\n Dark Chapel\n Mountain Cave\n{CHOICE2}" tt['intro_main'] = CompressedTextMapper.convert( "{INTRO}\n Episode III\n{PAUSE3}\n A Link to\n the Past\n" + "{PAUSE3}\nInverted\n Randomizer\n{PAUSE3}\nAfter mostly disregarding what happened in the first two games.\n" diff --git a/Text.py b/Text.py index c84a202c..76d94586 100644 --- a/Text.py +++ b/Text.py @@ -628,7 +628,7 @@ class MultiByteCoreTextMapper(object): @classmethod def convert(cls, text, pause=True, wrap=14): - text = text.upper() + #text = text.upper() lines = text.split('\n') outbuf = bytearray() lineindex = 0 @@ -772,20 +772,24 @@ class CompressedTextMapper(object): class CharTextMapper(object): number_offset = None alpha_offset = 0 + alpha_lower_offset = 0 char_map = {} @classmethod def map_char(cls, char): if cls.number_offset is not None: if 0x30 <= ord(char) <= 0x39: return ord(char) + cls.number_offset + if 0x41 <= ord(char) <= 0x5A: + return ord(char) + 0x20 + cls.alpha_offset if 0x61 <= ord(char) <= 0x7A: - return ord(char) + cls.alpha_offset + return ord(char) + cls.alpha_lower_offset return cls.char_map.get(char, cls.char_map[' ']) @classmethod def convert(cls, text): buf = bytearray() - for char in text.lower(): + #for char in text.lower(): + for char in text: buf.append(cls.map_char(char)) return buf @@ -1240,6 +1244,7 @@ class RawMBTextMapper(CharTextMapper): "月": 0xFE, "姫": 0xFF} alpha_offset = 0x49 + alpha_lower_offset = -0x31 number_offset = 0x70 @classmethod @@ -1251,7 +1256,8 @@ class RawMBTextMapper(CharTextMapper): @classmethod def convert(cls, text): buf = bytearray() - for char in text.lower(): + #for char in text.lower(): + for char in text: res = cls.map_char(char) if isinstance(res, int): buf.extend([0x00, res]) @@ -1267,16 +1273,19 @@ class GoldCreditMapper(CharTextMapper): '-': 0x36, '.': 0x37,} alpha_offset = -0x47 + alpha_lower_offset = -0x47 class GreenCreditMapper(CharTextMapper): char_map = {' ': 0x9F, '·': 0x52} alpha_offset = -0x29 + alpha_lower_offset = -0x29 class RedCreditMapper(CharTextMapper): char_map = {' ': 0x9F} alpha_offset = -0x61 + alpha_lower_offset = -0x61 class LargeCreditTopMapper(CharTextMapper): char_map = {' ': 0x9F, @@ -1296,6 +1305,7 @@ class LargeCreditTopMapper(CharTextMapper): '◢': 0xAA, '◣': 0xAB,} alpha_offset = -0x04 + alpha_lower_offset = -0x04 number_offset = 0x23 @@ -1317,6 +1327,7 @@ class LargeCreditBottomMapper(CharTextMapper): '◢': 0xCA, '◣': 0xCB,} alpha_offset = 0x22 + alpha_lower_offset = 0x22 number_offset = 0x49 class TextTable(object): @@ -1903,7 +1914,7 @@ class TextTable(object): text['pond_of_wishing_good_luck'] = CompressedTextMapper.convert("\n is good luck") text['pond_of_wishing_meh_luck'] = CompressedTextMapper.convert("\n is meh luck") # Repurposed to no items in Randomizer - text['pond_of_wishing_bad_luck'] = CompressedTextMapper.convert("Why you come in here and pretend like you have something this fountain wants? Come back with bottles!") + text['pond_of_wishing_bad_luck'] = CompressedTextMapper.convert("Why come in here and pretend like you have something this fountain wants? Come back with bottles!") text['pond_of_wishing_fortune'] = CompressedTextMapper.convert("by the way, your fortune,") text['item_get_14_heart'] = CompressedTextMapper.convert("3 more to go\n ¼\nYay!") text['item_get_24_heart'] = CompressedTextMapper.convert("2 more to go\n ½\nWhee!") @@ -1955,16 +1966,16 @@ class TextTable(object): text['game_chest_lost_woods'] = CompressedTextMapper.convert("Pay 100 rupees open 1 chest. Are you lucky?\nSo, Play game?\n ≥ play\n never!\n{CHOICE}") text['kakariko_flophouse_man_no_flippers'] = CompressedTextMapper.convert("I really hate mowing my yard.\nI moved my house and everyone else's to avoid it.\n{PAGEBREAK}\nI hope you don't mind.") text['kakariko_flophouse_man'] = CompressedTextMapper.convert("I really hate mowing my yard.\nI moved my house and everyone else's to avoid it.\n{PAGEBREAK}\nI hope you don't mind.") - text['menu_start_2'] = CompressedTextMapper.convert("{MENU}\n{SPEED0}\n≥@'s house\n Sanctuary\n{CHOICE3}", False) - text['menu_start_3'] = CompressedTextMapper.convert("{MENU}\n{SPEED0}\n≥@'s house\n Sanctuary\n Mountain Cave\n{CHOICE2}", False) - text['menu_pause'] = CompressedTextMapper.convert("{SPEED0}\n≥continue\n save and quit\n{CHOICE3}", False) + text['menu_start_2'] = CompressedTextMapper.convert("{MENU}\n{SPEED0}\n≥@'s House\n Sanctuary\n{CHOICE3}", False) + text['menu_start_3'] = CompressedTextMapper.convert("{MENU}\n{SPEED0}\n≥@'s House\n Sanctuary\n Mountain Cave\n{CHOICE2}", False) + text['menu_pause'] = CompressedTextMapper.convert("{SPEED0}\n≥Continue\n Save and Quit\n{CHOICE3}", False) text['game_digging_choice'] = CompressedTextMapper.convert("Have 80 Rupees? Want to play digging game?\n ≥yes\n no\n{CHOICE}") text['game_digging_start'] = CompressedTextMapper.convert("Okay, use the shovel with Y!") text['game_digging_no_cash'] = CompressedTextMapper.convert("Shovel rental is 80 rupees.\nI have all day") text['game_digging_end_time'] = CompressedTextMapper.convert("Time's up!\nTime for you to go.") text['game_digging_come_back_later'] = CompressedTextMapper.convert("Come back later, I have to bury things.") text['game_digging_no_follower'] = CompressedTextMapper.convert("Something is following you. I don't like.") - text['menu_start_4'] = CompressedTextMapper.convert("{MENU}\n{SPEED0}\n≥@'s house\n Mountain Cave\n{CHOICE3}", False) + text['menu_start_4'] = CompressedTextMapper.convert("{MENU}\n{SPEED0}\n≥@'s House\n Mountain Cave\n{CHOICE3}", False) # Start of new text data text['ganon_fall_in_alt'] = CompressedTextMapper.convert("You think you\nare ready to\nface me?\n\nI will not die\n\nunless you\ncomplete your\ngoals. Dingus!") text['ganon_phase_3_alt'] = CompressedTextMapper.convert("Got wax in\nyour ears?\nI cannot die!") diff --git a/data/base2current.bps b/data/base2current.bps index c8e8cbb4c4d9264203601dd8adf818b9abb45977..82223df24a7456e2e40e35b6862203f12b23f6a3 100644 GIT binary patch delta 418 zcmWlT%}WAN6vgk9LbR%&pls73XgN84G2@KP_`ztjh@xc#ErNDox}En7Bn27lEd~(@ zDRCiz6QoH=K?^tj0qv?y3GUlYcUJG*-#PEx+Zuas$KGy|^Q<2HbS~3eKh1Ibx}iV< z90&ssNeG|{f=gr&au7%Cq9~d%d=&^9hL37y5^1{Z1#eE&Jvf@ZmI4B3F72_YnV}^e9OfZZ zwMOkAeV?JF6!6wG!)o5S_sd@>-(V{?ssi& LvUfMlt>h>F9N>+c delta 420 zcmWlTKTE?<6vc1+hd2o$h`KoFCUj5=3c4s*MO2*a<_9QRoh0uySWwX*j}l4;5s^S_ z(xfzhBuQH;(xo53O&p|?pP`;i@4nwX=iKws8-4AK+S}4duKzHjWF$W$Nyj^KKusEu zLk6|T!c?P#_+;iO22PNNS7^w5nd%Lff0H)D;rGpJ_9s}66Qe~CFjI6Q->5DYF&Mm ze+==PHW^xfS6W>1yXzb$JJ1xhE9E71J`DFE@u%g};?&L1A4v{(QD From b13712aabf3912c0cba13dd89616e74872da8b44 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 6 Feb 2022 15:39:07 -0600 Subject: [PATCH 65/73] Enabled new font + lowercase hint text updates --- Text.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Text.py b/Text.py index 76d94586..e63926f3 100644 --- a/Text.py +++ b/Text.py @@ -627,7 +627,7 @@ class MultiByteCoreTextMapper(object): } @classmethod - def convert(cls, text, pause=True, wrap=14): + def convert(cls, text, pause=True, wrap=19): #text = text.upper() lines = text.split('\n') outbuf = bytearray() @@ -736,7 +736,7 @@ class CompressedTextMapper(object): } @classmethod - def convert(cls, text, pause=True, max_bytes_expanded=0x800, wrap=14): + def convert(cls, text, pause=True, max_bytes_expanded=0x800, wrap=19): inbuf = MultiByteCoreTextMapper.convert(text, pause, wrap) # Links name will need 8 bytes in the target buffer From 05a7a99115b436ad308ad9fe631910af050693ff Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 6 Feb 2022 21:43:50 -0600 Subject: [PATCH 66/73] Enabled new font + lowercase hint text updates --- Text.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Text.py b/Text.py index e63926f3..5257dc40 100644 --- a/Text.py +++ b/Text.py @@ -655,7 +655,7 @@ class MultiByteCoreTextMapper(object): pending_space = False while words: word = words.pop(0) - # sanity check: if the word we have is more than 14 characters, we take as much as we can still fit and push the rest back for later + # sanity check: if the word we have is more than 19 characters, we take as much as we can still fit and push the rest back for later if cls.wordlen(word) > wrap: (word_first, word_rest) = cls.splitword(word, linespace) words.insert(0, word_rest) From 85bdc93a5a14510ad45d3403304e39ea3e6b3657 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Feb 2022 15:32:40 -0600 Subject: [PATCH 67/73] Fixed issue with OWR Layout+Shopsanity --- OverworldShuffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index e535366f..a995e09f 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1110,7 +1110,7 @@ def validate_layout(world, player): if entrance.name not in drop_entrances \ and ((entrance.name in dungeon_entrances and world.shuffle[player] not in ['dungeonssimple', 'simple', 'restricted']) \ or (entrance.name in connector_entrances and world.shuffle[player] not in ['dungeonssimple', 'dungeonsfull', 'simple']) \ - or (entrance.name in item_entrances + ([] if world.shopsanity[player] else shop_entrances) and world.shuffle[player] not in ['dungeonssimple', 'dungeonsfull', 'lite', 'lean'])): + or (entrance.name in item_entrances + (tuple() if world.shopsanity[player] else shop_entrances) and world.shuffle[player] not in ['dungeonssimple', 'dungeonsfull', 'lite', 'lean'])): unreachable_regions.pop(region_name) explore_region(region_name) break From f07ea8126c911bf5d95021bdf2344011b90b6265 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Feb 2022 15:32:58 -0600 Subject: [PATCH 68/73] Fixed issue with OWR Layout + Insanity ER --- OverworldShuffle.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index a995e09f..03eb7375 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1083,7 +1083,8 @@ def validate_layout(world, player): flat_sectors = [[r for l in s for r in l] for s in world.owsectors[player]] for sector in flat_sectors: for region_name in sector: - if region_name not in explored_regions and region_name not in isolated_regions: + if region_name not in explored_regions and region_name not in isolated_regions \ + and not (region_name == 'Pyramid Exit Ledge' and world.shuffle[player] == 'insanity'): region = base_world.get_region(region_name, player) unreachable_regions[region_name] = region From b04968beeecc74bf58b8fbe292ccae39ceb2dc20 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Feb 2022 15:37:12 -0600 Subject: [PATCH 69/73] Fixed issue with OWR Layout + Insanity ER --- OverworldShuffle.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 03eb7375..bef894a3 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1083,8 +1083,7 @@ def validate_layout(world, player): flat_sectors = [[r for l in s for r in l] for s in world.owsectors[player]] for sector in flat_sectors: for region_name in sector: - if region_name not in explored_regions and region_name not in isolated_regions \ - and not (region_name == 'Pyramid Exit Ledge' and world.shuffle[player] == 'insanity'): + if region_name not in explored_regions and region_name not in isolated_regions: region = base_world.get_region(region_name, player) unreachable_regions[region_name] = region @@ -1895,7 +1894,8 @@ isolated_regions = [ 'Dark Death Mountain Floating Island', 'Dark Death Mountain Ledge', 'Dark Death Mountain Isolated Ledge', - 'Bumper Cave Ledge' + 'Bumper Cave Ledge', + 'Pyramid Exit Ledge' ] flute_data = { From c375c120e94d742488e4abd59e426c75e4931310 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Feb 2022 18:00:31 -0600 Subject: [PATCH 70/73] Fixed issue with TR Peg Puzzle Portal not working --- Rom.py | 2 +- data/base2current.bps | Bin 91683 -> 91666 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index 3d910b80..f999192e 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '57d36048e54cd5a281f1dbf66f2bc9c2' +RANDOMIZERBASEHASH = 'b373b217fbbb529636f3bf507b8879b3' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 82223df24a7456e2e40e35b6862203f12b23f6a3..9ccd929c92479775ba957f72f3156f5f538d97e7 100644 GIT binary patch delta 2953 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 From 46cf11e8a37869089e52a00cdccd51cdae04d88e Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Feb 2022 19:21:04 -0600 Subject: [PATCH 71/73] Fixed issue with TR Peg Puzzle Portal not working --- Rom.py | 2 +- data/base2current.bps | Bin 91666 -> 91653 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index f999192e..a714cb16 100644 --- a/Rom.py +++ b/Rom.py @@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'b373b217fbbb529636f3bf507b8879b3' +RANDOMIZERBASEHASH = 'b46e08bfb572876dd51dc3108e7b9292' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 9ccd929c92479775ba957f72f3156f5f538d97e7..b1c892c64de471dd24da8364acc172f3914a3e78 100644 GIT binary patch delta 2831 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 ciwQ Date: Thu, 10 Feb 2022 21:05:42 -0600 Subject: [PATCH 72/73] Capitalizing first letter of hint tiles --- Rom.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Rom.py b/Rom.py index a714cb16..a9e807cd 100644 --- a/Rom.py +++ b/Rom.py @@ -2304,6 +2304,7 @@ def write_strings(rom, world, player, team): this_location = world.find_items_not_key_only(flute_item, player) if this_location: this_hint = this_location[0].item.hint_text + ' can be found ' + hint_text(this_location[0]) + '.' + this_hint = this_hint.capitalize() tt[hint_locations.pop(0)] = this_hint items_to_hint.remove(flute_item) if world.keyshuffle[player]: @@ -2320,6 +2321,7 @@ def write_strings(rom, world, player, team): random.shuffle(this_location) if this_location: this_hint = this_location[0].item.hint_text + ' can be found ' + hint_text(this_location[0]) + '.' + this_hint = this_hint.capitalize() tt[hint_locations.pop(0)] = this_hint hint_count -= 1 From 4bbf0f6d4fc6d3db59703210b7019a1b1b61e5db Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 10 Feb 2022 21:22:53 -0600 Subject: [PATCH 73/73] Version bump 0.2.6.0 --- CHANGELOG.md | 8 ++++++++ OverworldShuffle.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ef9d2a1..0d41ef2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +### 0.2.6.0 +- New text engine font! +- Fixed invisible Witch item bug +- Added 'O' to ROM Header for autotrackers +- Fixed generation error with Shopsanity + OWR Layout +- Fixed OWR validation error with Insanity ER + OWR Layout +- Fixed issue with TR Peg Puzzle not spawning a valid portal + ### 0.2.5.3 - Changed AT/GT Swap to favor vanilla, only swapping if GT entrance is the only choice in starting world - Fixed issue with Links House not swapping in OW Mixed diff --git a/OverworldShuffle.py b/OverworldShuffle.py index bef894a3..ed5e914b 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -5,7 +5,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl from Regions import mark_dark_world_regions, mark_light_world_regions from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel -__version__ = '0.2.5.3-u' +__version__ = '0.2.6.0-u' def link_overworld(world, player): # setup mandatory connections