From 940369d3ec9221583a3fea336b4e9e8d726ce6b4 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 9 Jul 2021 15:13:01 -0700 Subject: [PATCH 01/21] Rename fake boots to pseudo boots Doc updates --- BaseClasses.py | 2 +- CLI.py | 4 ++-- Main.py | 4 ++-- Mystery.py | 2 +- RELEASENOTES.md | 13 ++++++++++++- Rom.py | 2 +- resources/app/cli/args.json | 2 +- resources/app/cli/lang/en.json | 2 +- resources/app/gui/lang/en.json | 2 +- resources/app/gui/randomize/item/widgets.json | 2 +- source/classes/constants.py | 2 +- 11 files changed, 24 insertions(+), 13 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 7521bd6e..0e3e8af4 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -131,7 +131,7 @@ class World(object): set_player_attr('treasure_hunt_total', 0) set_player_attr('potshuffle', False) set_player_attr('pot_contents', None) - set_player_attr('fakeboots', False) + set_player_attr('pseudoboots', False) set_player_attr('shopsanity', False) set_player_attr('keydropshuffle', False) diff --git a/CLI.py b/CLI.py index 9b6e42fb..d87e1e2c 100644 --- a/CLI.py +++ b/CLI.py @@ -97,7 +97,7 @@ def parse_cli(argv, no_defaults=False): 'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', 'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max', - 'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'fakeboots', + 'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'pseudoboots', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', 'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots', 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep', @@ -144,7 +144,7 @@ def parse_settings(): "shuffleganon": True, "shuffle": "vanilla", "shufflelinks": False, - "fakeboots": False, + "pseudoboots": False, "shufflepots": False, "shuffleenemies": "none", diff --git a/Main.py b/Main.py index 9e8f1e7c..73b60974 100644 --- a/Main.py +++ b/Main.py @@ -27,7 +27,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.4.0.9-u' +__version__ = '0.4.0.10u' class EnemizerError(RuntimeError): @@ -90,7 +90,7 @@ def main(args, seed=None, fish=None): world.treasure_hunt_count = args.triforce_goal.copy() world.treasure_hunt_total = args.triforce_pool.copy() world.shufflelinks = args.shufflelinks.copy() - world.fakeboots = args.fakeboots.copy() + world.pseudoboots = args.pseudoboots.copy() world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)} diff --git a/Mystery.py b/Mystery.py index 0fd85108..f82e64d2 100644 --- a/Mystery.py +++ b/Mystery.py @@ -143,7 +143,7 @@ def roll_settings(weights): ret.dungeon_counters = 'pickup' if ret.door_shuffle != 'vanilla' or ret.compassshuffle == 'on' else 'off' ret.shufflelinks = get_choice('shufflelinks') == 'on' - ret.fakeboots = get_choice('fakeboots') == 'on' + ret.pseudoboots = get_choice('pseudoboots') == 'on' ret.shopsanity = get_choice('shopsanity') == 'on' ret.keydropshuffle = get_choice('keydropshuffle') == 'on' ret.mixed_travel = get_choice('mixed_travel') if 'mixed_travel' in weights else 'prevent' diff --git a/RELEASENOTES.md b/RELEASENOTES.md index a4c5eace..d55904b8 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -12,8 +12,19 @@ Links house can now be shuffled in different ER settings. It will be limited to Thanks to qadan, cheuer, & compiling +## Pseudo Boots + +Thanks to Bonta. You can now start with pseudo boots that let you move fast, but have no other logical uses (bonking open things, hovering, etc) + +## Pendant/Crystal Indicator + +For accessibility, you now get a C or P indicator to the left of the magic bar on the HUD when instead a Crystal or Pendant. Requires ownership of the map of that dungeon for display. Thanks to kan. + # Bug Fixes and Notes. +* 0.4.0.10 + * Renamed to pseudoboots + * Some release note updates * 0.4.0.9 * Fixes for stats and P/C indicator (thanks Kara) * Swamp lobby fixes (thanks Catobat) @@ -38,7 +49,7 @@ Thanks to qadan, cheuer, & compiling * Chest turn tracking (not yet in credits) * Damaged and magic stats in credits (gt bk removed) * Fix for infinite bombs - * Fake boots option + * Pseudo boots option * Always allowed medallions for swordless (no option yet) * 0.4.0.7 * Reduce flashing option added diff --git a/Rom.py b/Rom.py index 64a32986..6c351828 100644 --- a/Rom.py +++ b/Rom.py @@ -1162,7 +1162,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x18017E, 0x01) # Fairy fountains only trade in bottles # Starting equipment - if world.fakeboots[player]: + if world.pseudoboots[player]: rom.write_byte(0x18008E, 0x01) equip = [0] * (0x340 + 0x4F) diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 874bc2f5..47bb3987 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -310,7 +310,7 @@ "action": "store_true", "type": "bool" }, - "fakeboots": { + "pseudoboots": { "action": "store_true", "type": "bool" }, diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index 6416e952..0ff910a9 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -262,7 +262,7 @@ "Keys are universal, shooting arrows costs rupees,", "and a few other little things make this more like Zelda-1. (default: %(default)s)" ], - "fakeboots": [ " Players starts with fake boots that allow dashing but no item checks (default: %(default)s"], + "pseudoboots": [ " Players starts with pseudo boots that allow dashing but no item checks (default: %(default)s"], "startinventory": [ "Specifies a list of items that will be in your starting inventory (separated by commas). (default: %(default)s)" ], "usestartinventory": [ "Toggle usage of Starting Inventory." ], "custom": [ "Not supported." ], diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index f4b8ca12..0d9e3836 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -189,7 +189,7 @@ "randomizer.item.hints": "Include Helpful Hints", "randomizer.item.retro": "Retro mode (universal keys)", - "randomizer.item.fakeboots": "Start with Fake Boots", + "randomizer.item.pseudoboots": "Start with Pseudo Boots", "randomizer.item.worldstate": "World State", "randomizer.item.worldstate.standard": "Standard", diff --git a/resources/app/gui/randomize/item/widgets.json b/resources/app/gui/randomize/item/widgets.json index 1f5eb19a..a6f10a14 100644 --- a/resources/app/gui/randomize/item/widgets.json +++ b/resources/app/gui/randomize/item/widgets.json @@ -5,7 +5,7 @@ "hints": { "type": "checkbox" }, - "fakeboots": { "type": "checkbox" } + "pseudoboots": { "type": "checkbox" } }, "leftItemFrame": { "worldstate": { diff --git a/source/classes/constants.py b/source/classes/constants.py index 14c70f79..04cbde2e 100644 --- a/source/classes/constants.py +++ b/source/classes/constants.py @@ -58,7 +58,7 @@ SETTINGSTOPROCESS = { "hints": "hints", "retro": "retro", "shopsanity": "shopsanity", - "fakeboots": "fakeboots", + "pseudoboots": "pseudoboots", "worldstate": "mode", "logiclevel": "logic", "goal": "goal", From 38f1d78f9ab4ca25fc23cffed11c84a98cf1ae8d Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 11 Jul 2021 12:25:24 -0500 Subject: [PATCH 02/21] Minor formatting --- Rom.py | 61 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/Rom.py b/Rom.py index 7d56fa35..f3587820 100644 --- a/Rom.py +++ b/Rom.py @@ -2413,18 +2413,18 @@ def set_inverted_mode(world, player, rom, inverted_buffer): for b in range(0x00, len(inverted_buffer)): inverted_buffer[b] = (inverted_buffer[b] & 0xFE) | ((inverted_buffer[b] + 1) % 2) - rom.write_byte(snes_to_pc(0x0283E0), 0xF0) # residual portals + rom.write_byte(snes_to_pc(0x0283E0), 0xF0) # residual portals rom.write_byte(snes_to_pc(0x02B34D), 0xF0) - rom.write_byte(snes_to_pc(0x06DB78), 0x8B) # dark-style portal + rom.write_byte(snes_to_pc(0x06DB78), 0x8B) # dark-style portal - rom.write_byte(snes_to_pc(0x0DB3C5), 0xC6) #vortex + rom.write_byte(snes_to_pc(0x0DB3C5), 0xC6) # vortex - rom.write_byte(snes_to_pc(0x07A3F4), 0xF0) # duck - rom.write_byte(snes_to_pc(0x08D40C), 0xD0) # morph poof - rom.write_byte(snes_to_pc(0x0ABFBB), 0x90) # move mirror portal indicator to correct map (0xB0 normally) - rom.write_byte(snes_to_pc(0x0280A6), 0xD0) # use starting point prompt instead of start at pyramid + rom.write_byte(snes_to_pc(0x07A3F4), 0xF0) # duck + rom.write_byte(snes_to_pc(0x08D40C), 0xD0) # morph poof + rom.write_byte(snes_to_pc(0x0ABFBB), 0x90) # move mirror portal indicator to correct map (0xB0 normally) + rom.write_byte(snes_to_pc(0x0280A6), 0xD0) # use starting point prompt instead of start at pyramid - write_int16(rom, snes_to_pc(0x02D8D4), 0x112) # change sanctuary spawn point to dark sanc + write_int16(rom, snes_to_pc(0x02D8D4), 0x112) # change sanctuary spawn point to dark sanc rom.write_bytes(snes_to_pc(0x02D8E8), [0x22, 0x22, 0x22, 0x23, 0x04, 0x04, 0x04, 0x05]) write_int16(rom, snes_to_pc(0x02D91A), 0x0400) write_int16(rom, snes_to_pc(0x02D928), 0x222E) @@ -2448,12 +2448,11 @@ def set_inverted_mode(world, player, rom, inverted_buffer): 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.mode[player] == 'inverted') != (0x03 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): if world.shuffle[player] in ['vanilla', 'dungeonsfull', 'dungeonssimple']: - rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) # mountain cave starts on OW + 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 + 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) @@ -2471,10 +2470,10 @@ def set_inverted_mode(world, player, rom, inverted_buffer): 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 + rom.write_bytes(0x180247, [0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00]) #indicates the overworld door being used for the single entrance spawn point rom.write_byte(0xDBB73 + 0x6F, 0x07) # DDM fairy entrance to old man fetch east UW - write_int16(rom, 0x15AEE + 2*0x18, 0x00F1) # old man fetch UW to DDM fairy entrance + write_int16(rom, 0x15AEE + 2*0x18, 0x00F1) # old man fetch UW to DDM fairy entrance rom.write_byte(0x15B8C + 0x18, 0x43) write_int16(rom, 0x15BDB + 2 * 0x18, 0x1400) write_int16(rom, 0x15C79 + 2 * 0x18, 0x0294) @@ -2488,17 +2487,17 @@ def set_inverted_mode(world, player, rom, inverted_buffer): write_int16(rom, 0x160CB + 2 * 0x18, 0x0000) write_int16(rom, 0x16169 + 2 * 0x18, 0x0000) - rom.write_byte(0xDBB73 + 0x06, 0x2E) # old man fetch east entrance to DMD west UW - write_int16(rom, 0x15AEE + 2*0x08, 0x00E6) # DMD west UW to old man fetch east entrance + rom.write_byte(0xDBB73 + 0x06, 0x2E) # old man fetch east entrance to DMD west UW + write_int16(rom, 0x15AEE + 2*0x08, 0x00E6) # DMD west UW to old man fetch east entrance if (world.mode[player] == 'inverted') != (0x0A in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): - rom.write_byte(0xDBB73 + 0x16, 0x5E) # bumper cave top entrance to DDM Fairy UW + rom.write_byte(0xDBB73 + 0x16, 0x5E) # bumper cave top entrance to DDM Fairy UW else: - rom.write_byte(0xDBB73 + 0x2D, 0x5E) # DMD west entrance to DDM Fairy + rom.write_byte(0xDBB73 + 0x2D, 0x5E) # DMD west entrance to DDM Fairy if (world.mode[player] == 'inverted') != (0x05 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) # add warp under rock if (world.mode[player] == 'inverted') != (0x07 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): rom.write_bytes(snes_to_pc(0x1BC387), [0xDD, 0xD1]) # add warps under rocks - rom.write_bytes(snes_to_pc(0x1BD1DD), [0xA4, 0x06, 0x82, 0x9E, 0x06, 0x82, 0xFF, 0xFF]) # add warps under rocks + 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 if world.shuffle[player] in ['vanilla']: @@ -2507,13 +2506,13 @@ def set_inverted_mode(world, player, rom, inverted_buffer): if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: rom.write_byte(0xDBB73 + 0x15, 0x06) # bumper cave bottom entrance to old man fetch west UW write_int16(rom, 0x15AEE + 2*0x17, 0x00F0) # old man fetch west UW to bumper cave bottom entrance - rom.write_byte(0xDBB73 + 0x05, 0x16) # old man fetch west entrance to bumper cave bottom UW - write_int16(rom, 0x15AEE + 2*0x07, 0x00FB) # bumper cave bottom UW to old man fetch west entrance - rom.write_byte(0xDBB73 + 0x2D, 0x17) # DMD west entrance to bumper cave top UW - write_int16(rom, 0x15AEE + 2*0x2F, 0x00EB) # bumper cave top UW to DMD west entrance + rom.write_byte(0xDBB73 + 0x05, 0x16) # old man fetch west entrance to bumper cave bottom UW + write_int16(rom, 0x15AEE + 2*0x07, 0x00FB) # bumper cave bottom UW to old man fetch west entrance + rom.write_byte(0xDBB73 + 0x2D, 0x17) # DMD west entrance to bumper cave top UW + write_int16(rom, 0x15AEE + 2*0x2F, 0x00EB) # bumper cave top UW to DMD west entrance if (world.mode[player] == 'inverted') == (0x03 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): - rom.write_byte(0xDBB73 + 0x16, 0x2E) # bumper cave top entrance to DMD west UW - write_int16(rom, 0x15AEE + 2*0x18, 0x00E6) # DMD west UW to bumper cave top entrance + rom.write_byte(0xDBB73 + 0x16, 0x2E) # bumper cave top entrance to DMD west UW + write_int16(rom, 0x15AEE + 2*0x18, 0x00E6) # DMD west UW to bumper cave top entrance if (world.mode[player] == 'inverted') != (0x10 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): rom.write_bytes(snes_to_pc(0x1BC67A), [0x2E, 0x0B, 0x82]) # add warp under rock if (world.mode[player] == 'inverted') != (0x1B in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): @@ -2552,7 +2551,7 @@ def set_inverted_mode(world, player, rom, inverted_buffer): rom.write_byte(snes_to_pc(0x00D009), 0x31) # castle hole graphics rom.write_byte(snes_to_pc(0x00D0E8), 0xE0) rom.write_byte(snes_to_pc(0x00D1C7), 0x00) - write_int16(rom, snes_to_pc(0x1BE8DA), 0x39AD) # add color for shading for castle hole + write_int16(rom, snes_to_pc(0x1BE8DA), 0x39AD) # add color for shading for castle hole #castle hole map16 data write_int16s(rom, snes_to_pc(0x0FF1C8), [0x190F, 0x190F, 0x190F, 0x194C, 0x190F, @@ -2566,21 +2565,21 @@ def set_inverted_mode(world, player, rom, inverted_buffer): write_int16s(rom, snes_to_pc(0x0FA480), [0x190F, 0x196B, 0x9D04, 0x9D04, 0x196B, 0x190F, 0x9D04, 0x9D04]) - write_int16s(rom, snes_to_pc(0x1BB810), [0x00BE, 0x00C0, 0x013E]) # update pyramid hole entrance + write_int16s(rom, snes_to_pc(0x1BB810), [0x00BE, 0x00C0, 0x013E]) # update pyramid hole entrance write_int16s(rom, snes_to_pc(0x1BB836), [0x001B, 0x001B, 0x001B]) - write_int16(rom, snes_to_pc(0x308300), 0x0140) #add extra pyramid hole + write_int16(rom, snes_to_pc(0x308300), 0x0140) # add extra pyramid hole write_int16(rom, snes_to_pc(0x308320), 0x001B) if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: rom.write_byte(snes_to_pc(0x308340), 0x7B) - rom.write_byte(snes_to_pc(0x00DB9D), 0x1A) # make retreat bat gfx available in HC area + rom.write_byte(snes_to_pc(0x00DB9D), 0x1A) # make retreat bat gfx available in HC area rom.write_byte(snes_to_pc(0x00DC09), 0x1A) rom.write_byte(snes_to_pc(0x1AF696), 0xF0) # bat sprite retreat : bat X position rom.write_byte(snes_to_pc(0x1AF6B2), 0x33) # bat sprite retreat : bat delay - write_int16(rom, snes_to_pc(0x1af504), 0x148B) # prioritize retreat Bat and use 3rd sprite group + write_int16(rom, snes_to_pc(0x1af504), 0x148B) # prioritize retreat Bat and use 3rd sprite group write_int16(rom, snes_to_pc(0x1af50c), 0x149B) write_int16(rom, snes_to_pc(0x1af514), 0x14A4) write_int16(rom, snes_to_pc(0x1af51c), 0x1489) @@ -2622,10 +2621,10 @@ def set_inverted_mode(world, player, rom, inverted_buffer): write_int16(rom, 0x160CB + 2 * 0x37, 0x0000) write_int16(rom, 0x16169 + 2 * 0x37, 0x811c) if (world.mode[player] == 'inverted') != (0x29 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): - rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) #frog pickup on contact + rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact if (world.mode[player] == 'inverted') != (0x2C in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - rom.write_byte(0x15B8C, 0x6C) #exit links at bomb shop area + 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) if (world.mode[player] == 'inverted') != (0x2F in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): From ab0625e41357176e0531ea09dcf4451189b1eb1c Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 11 Jul 2021 12:26:09 -0500 Subject: [PATCH 03/21] Fixed issue with Pyramid Exit leading to vanilla Pyramid Exit Ledge instead of HC Ledge --- Rom.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/Rom.py b/Rom.py index f3587820..c2b8d1d5 100644 --- a/Rom.py +++ b/Rom.py @@ -2603,23 +2603,21 @@ def set_inverted_mode(world, player, rom, inverted_buffer): write_int16(rom, 0xDB96F + 2 * 0x35, 0x001B) # move pyramid exit door write_int16(rom, 0xDBA71 + 2 * 0x35, 0x011C) - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - rom.write_byte(0xDBB73 + 0x35, 0x36) + rom.write_byte(0xDBB73 + 0x35, 0x36) - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - write_int16(rom, 0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area - rom.write_byte(0x15B8C + 0x37, 0x1B) - write_int16(rom, 0x15BDB + 2 * 0x37, 0x000E) - write_int16(rom, 0x15C79 + 2 * 0x37, 0x0600) - write_int16(rom, 0x15D17 + 2 * 0x37, 0x0676) - write_int16(rom, 0x15DB5 + 2 * 0x37, 0x0604) - write_int16(rom, 0x15E53 + 2 * 0x37, 0x06E8) - write_int16(rom, 0x15EF1 + 2 * 0x37, 0x066D) - write_int16(rom, 0x15F8F + 2 * 0x37, 0x06F3) - rom.write_byte(0x1602D + 0x37, 0x00) - rom.write_byte(0x1607C + 0x37, 0x0A) - write_int16(rom, 0x160CB + 2 * 0x37, 0x0000) - write_int16(rom, 0x16169 + 2 * 0x37, 0x811c) + write_int16(rom, 0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area + rom.write_byte(0x15B8C + 0x37, 0x1B) + write_int16(rom, 0x15BDB + 2 * 0x37, 0x000E) + write_int16(rom, 0x15C79 + 2 * 0x37, 0x0600) + write_int16(rom, 0x15D17 + 2 * 0x37, 0x0676) + write_int16(rom, 0x15DB5 + 2 * 0x37, 0x0604) + write_int16(rom, 0x15E53 + 2 * 0x37, 0x06E8) + write_int16(rom, 0x15EF1 + 2 * 0x37, 0x066D) + write_int16(rom, 0x15F8F + 2 * 0x37, 0x06F3) + rom.write_byte(0x1602D + 0x37, 0x00) + rom.write_byte(0x1607C + 0x37, 0x0A) + write_int16(rom, 0x160CB + 2 * 0x37, 0x0000) + write_int16(rom, 0x16169 + 2 * 0x37, 0x811C) if (world.mode[player] == 'inverted') != (0x29 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact if (world.mode[player] == 'inverted') != (0x2C in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): From 8ca7189dc136654a0c6155c96aaaf2ec6f8c39c6 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 11 Jul 2021 14:45:27 -0500 Subject: [PATCH 04/21] Consolidated some logic for Vanilla/Dungeon ER --- EntranceShuffle.py | 184 +++++++++++++++++++++------------------------ 1 file changed, 84 insertions(+), 100 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 54608e08..97998fc2 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -28,123 +28,107 @@ def link_entrances(world, player): connect_custom(world, player) # if we do not shuffle, set default connections - if world.shuffle[player] == 'vanilla': + if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: for exitname, regionname in default_connections: connect_simple(world, exitname, regionname, player) - for exitname, regionname in default_dungeon_connections: - connect_simple(world, exitname, regionname, player) + if world.shuffle[player] == 'vanilla': + for exitname, regionname in default_dungeon_connections: + connect_simple(world, exitname, regionname, player) if not invFlag: for exitname, regionname in open_default_connections: connect_simple(world, exitname, regionname, player) - for exitname, regionname in open_default_dungeon_connections: - connect_simple(world, exitname, regionname, player) + if world.shuffle[player] == 'vanilla': + for exitname, regionname in open_default_dungeon_connections: + connect_simple(world, exitname, regionname, player) else: for exitname, regionname in inverted_default_connections: connect_simple(world, exitname, regionname, player) - for exitname, regionname in inverted_default_dungeon_connections: - connect_simple(world, exitname, regionname, player) - elif world.shuffle[player] == 'dungeonssimple': - for exitname, regionname in default_connections: - connect_simple(world, exitname, regionname, player) + if world.shuffle[player] == 'vanilla': + for exitname, regionname in inverted_default_dungeon_connections: + connect_simple(world, exitname, regionname, player) - if not invFlag: - for exitname, regionname in open_default_connections: - connect_simple(world, exitname, regionname, player) - else: - for exitname, regionname in inverted_default_connections: - connect_simple(world, exitname, regionname, player) - - simple_shuffle_dungeons(world, player) - elif world.shuffle[player] == 'dungeonsfull': - for exitname, regionname in default_connections: - connect_simple(world, exitname, regionname, player) - - if not invFlag: - for exitname, regionname in open_default_connections: - connect_simple(world, exitname, regionname, player) - else: - for exitname, regionname in inverted_default_connections: - connect_simple(world, exitname, regionname, player) + if world.shuffle[player] == 'dungeonssimple': + simple_shuffle_dungeons(world, player) + elif world.shuffle[player] == 'dungeonsfull': + skull_woods_shuffle(world, player) - skull_woods_shuffle(world, player) + dungeon_exits = list(Dungeon_Exits) + lw_entrances = list(LW_Dungeon_Entrances) if not invFlag else list(Inverted_LW_Dungeon_Entrances_Must_Exit) + dw_entrances = list(DW_Dungeon_Entrances) if not invFlag else list(Inverted_DW_Dungeon_Entrances) - dungeon_exits = list(Dungeon_Exits) - lw_entrances = list(LW_Dungeon_Entrances) if not invFlag else list(Inverted_LW_Dungeon_Entrances_Must_Exit) - dw_entrances = list(DW_Dungeon_Entrances) if not invFlag else list(Inverted_DW_Dungeon_Entrances) - - if world.mode[player] != 'standard': - lw_entrances.append('Hyrule Castle Entrance (South)') - - if not invFlag: - if world.mode[player] == 'standard': - # must connect front of hyrule castle to do escape - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) - elif world.doorShuffle[player] == 'vanilla': - dungeon_exits.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) - else: - lw_dungeon_entrances_must_exit = list(Inverted_LW_Dungeon_Entrances_Must_Exit) - # randomize which desert ledge door is a must-exit - if random.randint(0, 1) == 0: - lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (North)') - lw_entrances.append('Desert Palace Entrance (West)') - else: - lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (West)') - lw_entrances.append('Desert Palace Entrance (North)') - dungeon_exits.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) - hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] - else: - if not invFlag: - dw_entrances.append('Ganons Tower') - else: - lw_entrances.append('Agahnims Tower') - dungeon_exits.append('Ganons Tower Exit') - hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower'] - - if not invFlag: - if world.mode[player] == 'standard': - # rest of hyrule castle must be in light world, so it has to be the one connected to east exit of desert - hyrule_castle_exits = [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')] - connect_mandatory_exits(world, lw_entrances, hyrule_castle_exits, list(LW_Dungeon_Entrances_Must_Exit), player) - connect_caves(world, lw_entrances, [], hyrule_castle_exits, player) - elif world.doorShuffle[player] != 'vanilla': - # sanc is in light world, so must all of HC if door shuffle is on - connect_mandatory_exits(world, lw_entrances, - [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)')], - list(LW_Dungeon_Entrances_Must_Exit), player) - else: - connect_mandatory_exits(world, lw_entrances, dungeon_exits, list(LW_Dungeon_Entrances_Must_Exit), player) - connect_mandatory_exits(world, dw_entrances, dungeon_exits, list(DW_Dungeon_Entrances_Must_Exit), player) - else: - # shuffle aga door first. If it's on HC ledge, remaining HC ledge door must be must-exit - all_entrances_aga = lw_entrances + dw_entrances - aga_doors = [i for i in all_entrances_aga] - random.shuffle(aga_doors) - aga_door = aga_doors.pop() + if world.mode[player] != 'standard': + lw_entrances.append('Hyrule Castle Entrance (South)') - if aga_door in hc_ledge_entrances: - lw_entrances.remove(aga_door) - hc_ledge_entrances.remove(aga_door) + if not invFlag: + if world.mode[player] == 'standard': + # must connect front of hyrule castle to do escape + connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) + elif world.doorShuffle[player] == 'vanilla': + dungeon_exits.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) + else: + lw_dungeon_entrances_must_exit = list(Inverted_LW_Dungeon_Entrances_Must_Exit) + # randomize which desert ledge door is a must-exit + if random.randint(0, 1) == 0: + lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (North)') + lw_entrances.append('Desert Palace Entrance (West)') + else: + lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (West)') + lw_entrances.append('Desert Palace Entrance (North)') + dungeon_exits.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) + hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'] + else: + if not invFlag: + dw_entrances.append('Ganons Tower') + else: + lw_entrances.append('Agahnims Tower') + dungeon_exits.append('Ganons Tower Exit') + hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower'] + + if not invFlag: + if world.mode[player] == 'standard': + # rest of hyrule castle must be in light world, so it has to be the one connected to east exit of desert + hyrule_castle_exits = [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')] + connect_mandatory_exits(world, lw_entrances, hyrule_castle_exits, list(LW_Dungeon_Entrances_Must_Exit), player) + connect_caves(world, lw_entrances, [], hyrule_castle_exits, player) + elif world.doorShuffle[player] != 'vanilla': + # sanc is in light world, so must all of HC if door shuffle is on + connect_mandatory_exits(world, lw_entrances, + [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Hyrule Castle Exit (South)')], + list(LW_Dungeon_Entrances_Must_Exit), player) + else: + connect_mandatory_exits(world, lw_entrances, dungeon_exits, list(LW_Dungeon_Entrances_Must_Exit), player) + connect_mandatory_exits(world, dw_entrances, dungeon_exits, list(DW_Dungeon_Entrances_Must_Exit), player) + else: + # shuffle aga door first. If it's on HC ledge, remaining HC ledge door must be must-exit + all_entrances_aga = lw_entrances + dw_entrances + aga_doors = [i for i in all_entrances_aga] + random.shuffle(aga_doors) + aga_door = aga_doors.pop() - random.shuffle(hc_ledge_entrances) - hc_ledge_must_exit = hc_ledge_entrances.pop() - lw_entrances.remove(hc_ledge_must_exit) - lw_dungeon_entrances_must_exit.append(hc_ledge_must_exit) + if aga_door in hc_ledge_entrances: + lw_entrances.remove(aga_door) + hc_ledge_entrances.remove(aga_door) + + random.shuffle(hc_ledge_entrances) + hc_ledge_must_exit = hc_ledge_entrances.pop() + lw_entrances.remove(hc_ledge_must_exit) + lw_dungeon_entrances_must_exit.append(hc_ledge_must_exit) - if aga_door in lw_entrances: - lw_entrances.remove(aga_door) - elif aga_door in dw_entrances: - dw_entrances.remove(aga_door) + if aga_door in lw_entrances: + lw_entrances.remove(aga_door) + elif aga_door in dw_entrances: + dw_entrances.remove(aga_door) - connect_two_way(world, aga_door, 'Agahnims Tower Exit', player) - dungeon_exits.remove('Agahnims Tower Exit') + connect_two_way(world, aga_door, 'Agahnims Tower Exit', player) + dungeon_exits.remove('Agahnims Tower Exit') - connect_mandatory_exits(world, lw_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player) - - connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player) + connect_mandatory_exits(world, lw_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player) + + connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player) elif world.shuffle[player] == 'simple': simple_shuffle_dungeons(world, player) From 6f990aecc180d8c14701ef37ab3e72a644f49bec Mon Sep 17 00:00:00 2001 From: Catobat <69204835+Catobat@users.noreply.github.com> Date: Mon, 12 Jul 2021 01:28:52 +0200 Subject: [PATCH 05/21] More bomb door candidates --- DoorShuffle.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 588c2857..00e787b9 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1704,25 +1704,14 @@ def smooth_door_pairs(world, player): remove_pair(door, world, player) if type_b == DoorKind.SmallKey: remove_pair(door, world, player) - elif type_a in [DoorKind.Bombable, DoorKind.Dashable] or type_b in [DoorKind.Bombable, DoorKind.Dashable]: + else: if valid_pair: - new_type = type_a - if type_a != type_b: - new_type = DoorKind.Dashable if type_a == DoorKind.Dashable or type_b == DoorKind.Dashable else DoorKind.Bombable - if type_a != new_type: - room_a.change(door.doorListPos, new_type) - if type_b != new_type: - room_b.change(partner.doorListPos, new_type) - add_pair(door, partner, world, player) - spoiler_type = 'Bomb Door' if new_type == DoorKind.Bombable else 'Dash Door' - world.spoiler.set_door_type(door.name + ' <-> ' + partner.name, spoiler_type, player) - counter = bombable_counts if new_type == DoorKind.Bombable else dashable_counts - counter[door.entrance.parent_region.dungeon] += 1 - else: + bd_candidates[door.entrance.parent_region.dungeon].append(door) + elif type_a in [DoorKind.Bombable, DoorKind.Dashable] or type_b in [DoorKind.Bombable, DoorKind.Dashable]: if type_a in [DoorKind.Bombable, DoorKind.Dashable]: room_a.change(door.doorListPos, DoorKind.Normal) remove_pair(door, world, player) - elif type_b in [DoorKind.Bombable, DoorKind.Dashable]: + else: room_b.change(partner.doorListPos, DoorKind.Normal) remove_pair(partner, world, player) elif valid_pair and type_a != DoorKind.SmallKey and type_b != DoorKind.SmallKey: From 0ade4c5795788b811662c377585c8d983723d6a7 Mon Sep 17 00:00:00 2001 From: Catobat <69204835+Catobat@users.noreply.github.com> Date: Mon, 12 Jul 2021 04:21:34 +0200 Subject: [PATCH 06/21] Counters no longer needed --- DoorShuffle.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 00e787b9..b3f8cb5e 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1678,7 +1678,7 @@ def change_door_to_small_key(d, world, player): def smooth_door_pairs(world, player): all_doors = [x for x in world.doors if x.player == player] skip = set() - bd_candidates, dashable_counts, bombable_counts = defaultdict(list), defaultdict(int), defaultdict(int) + bd_candidates = defaultdict(list) for door in all_doors: if door.type in [DoorType.Normal, DoorType.Interior] and door not in skip and not door.entranceFlag: partner = door.dest @@ -1716,7 +1716,7 @@ def smooth_door_pairs(world, player): remove_pair(partner, world, player) elif valid_pair and type_a != DoorKind.SmallKey and type_b != DoorKind.SmallKey: bd_candidates[door.entrance.parent_region.dungeon].append(door) - shuffle_bombable_dashable(bd_candidates, bombable_counts, dashable_counts, world, player) + shuffle_bombable_dashable(bd_candidates, world, player) world.paired_doors[player] = [x for x in world.paired_doors[player] if x.pair or x.original] @@ -1753,15 +1753,15 @@ def stateful_door(door, kind): return False -def shuffle_bombable_dashable(bd_candidates, bombable_counts, dashable_counts, world, player): +def shuffle_bombable_dashable(bd_candidates, world, player): if world.doorShuffle[player] == 'basic': for dungeon, candidates in bd_candidates.items(): - diff = bomb_dash_counts[dungeon.name][1] - dashable_counts[dungeon] + diff = bomb_dash_counts[dungeon.name][1] if diff > 0: for chosen in random.sample(candidates, min(diff, len(candidates))): change_pair_type(chosen, DoorKind.Dashable, world, player) candidates.remove(chosen) - diff = bomb_dash_counts[dungeon.name][0] - bombable_counts[dungeon] + diff = bomb_dash_counts[dungeon.name][0] if diff > 0: for chosen in random.sample(candidates, min(diff, len(candidates))): change_pair_type(chosen, DoorKind.Bombable, world, player) @@ -1770,16 +1770,12 @@ def shuffle_bombable_dashable(bd_candidates, bombable_counts, dashable_counts, w remove_pair_type_if_present(excluded, world, player) elif world.doorShuffle[player] == 'crossed': all_candidates = sum(bd_candidates.values(), []) - all_bomb_counts = sum(bombable_counts.values()) - all_dash_counts = sum(dashable_counts.values()) - if all_dash_counts < 8: - for chosen in random.sample(all_candidates, min(8 - all_dash_counts, len(all_candidates))): - change_pair_type(chosen, DoorKind.Dashable, world, player) - all_candidates.remove(chosen) - if all_bomb_counts < 12: - for chosen in random.sample(all_candidates, min(12 - all_bomb_counts, len(all_candidates))): - change_pair_type(chosen, DoorKind.Bombable, world, player) - all_candidates.remove(chosen) + for chosen in random.sample(all_candidates, min(8, len(all_candidates))): + change_pair_type(chosen, DoorKind.Dashable, world, player) + all_candidates.remove(chosen) + for chosen in random.sample(all_candidates, min(12, len(all_candidates))): + change_pair_type(chosen, DoorKind.Bombable, world, player) + all_candidates.remove(chosen) for excluded in all_candidates: remove_pair_type_if_present(excluded, world, player) From fc2457678f9f82745bc8abf33e455a8786b822bd Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 12 Jul 2021 01:51:22 -0500 Subject: [PATCH 07/21] Allowed Mountain Entry and West DM to be shuffled independenty in OW Tile Swap --- EntranceShuffle.py | 85 ++++++++++++++++++++++++++-------------------- OWEdges.py | 2 +- Rom.py | 48 -------------------------- 3 files changed, 49 insertions(+), 86 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 97998fc2..f73f0ea3 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -47,7 +47,24 @@ def link_entrances(world, player): if world.shuffle[player] == 'vanilla': for exitname, regionname in inverted_default_dungeon_connections: connect_simple(world, exitname, regionname, player) + + # inverted entrance mods + for owid in swapped_connections.keys(): + if (world.mode[player] == 'inverted') != (owid in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + 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.mode[player] == 'inverted') != (0x03 in world.owswaps[player][0] and world.owSwap[player] == 'mixed') and \ + (world.mode[player] == 'inverted') == (0x0a in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + connect_entrance(world, 'Death Mountain Return Cave (West)', 'Dark Death Mountain Healer Fairy', player) + elif (world.mode[player] == 'inverted') != (0x0a in world.owswaps[player][0] and world.owSwap[player] == 'mixed') and \ + (world.mode[player] == 'inverted') == (0x03 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): + connect_two_way(world, 'Bumper Cave (Top)', 'Death Mountain Return Cave Exit (West)', player) + + # dungeon entrance shuffle if world.shuffle[player] == 'dungeonssimple': simple_shuffle_dungeons(world, player) elif world.shuffle[player] == 'dungeonsfull': @@ -1533,7 +1550,9 @@ def connect_entrance(world, entrancename, exitname, player): addresses = door_addresses[entrance.name][0] entrance.connect(region, addresses, target) - world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance', player) + + if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance', player) def connect_exit(world, exitname, entrancename, player): entrance = world.get_entrance(entrancename, player) @@ -1544,7 +1563,9 @@ def connect_exit(world, exitname, entrancename, player): exit.connected_region.entrances.remove(exit) exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) - world.spoiler.set_entrance(entrance.name, exit.name, 'exit', player) + + if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + world.spoiler.set_entrance(entrance.name, exit.name, 'exit', player) def connect_two_way(world, entrancename, exitname, player): @@ -1559,7 +1580,9 @@ def connect_two_way(world, entrancename, exitname, player): entrance.connect(exit.parent_region, door_addresses[entrance.name][0], exit_ids[exit.name][0]) exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) - world.spoiler.set_entrance(entrance.name, exit.name, 'both', player) + + if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + world.spoiler.set_entrance(entrance.name, exit.name, 'both', player) def scramble_holes(world, player): @@ -2853,46 +2876,34 @@ default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'), ('Pyramid Hole', 'Pyramid'), ('Pyramid Entrance', 'Bottom of Pyramid'), ('Inverted Pyramid Hole', 'Pyramid'), - ('Inverted Pyramid Entrance', 'Bottom of Pyramid') + ('Inverted Pyramid Entrance', 'Bottom of Pyramid'), + ('Pyramid Exit', 'Pyramid Exit Ledge') ] -open_default_connections = [('Old Man Cave (West)', 'Old Man Cave Ledge'), - ('Old Man Cave (East)', 'Old Man Cave'), - ('Old Man Cave Exit (West)', 'Mountain Entry Entrance'), - ('Old Man Cave Exit (East)', 'West Death Mountain (Bottom)'), - ('Death Mountain Return Cave (East)', 'Death Mountain Return Cave'), - ('Death Mountain Return Cave (West)', 'Death Mountain Return Cave'), - ('Death Mountain Return Cave Exit (West)', 'Mountain Entry Ledge'), - ('Death Mountain Return Cave Exit (East)', 'West Death Mountain (Bottom)'), - ('Bumper Cave (Bottom)', 'Bumper Cave'), - ('Bumper Cave (Top)', 'Bumper Cave'), - ('Bumper Cave Exit (Top)', 'Bumper Cave Ledge'), - ('Bumper Cave Exit (Bottom)', 'Bumper Cave Entrance'), - ('Dark Death Mountain Fairy', 'Dark Death Mountain Healer Fairy'), +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') + ], + 0x1b: [ + ('Inverted Pyramid Entrance', 'Pyramid Exit') + ] +} - ('Links House', 'Links House'), +open_default_connections = [('Links House', 'Links House'), ('Links House Exit', 'Links House Area'), - ('Big Bomb Shop', 'Big Bomb Shop'), - ('Pyramid Exit', 'Pyramid Exit Ledge')] + ('Big Bomb Shop', 'Big Bomb Shop')] -inverted_default_connections = [('Old Man Cave (West)', 'Bumper Cave'), - ('Old Man Cave (East)', 'Death Mountain Return Cave'), - ('Old Man Cave Exit (West)', 'Bumper Cave Entrance'), - ('Old Man Cave Exit (East)', 'West Dark Death Mountain (Bottom)'), - ('Death Mountain Return Cave (West)', 'Bumper Cave'), - ('Death Mountain Return Cave (East)', 'Death Mountain Return Cave'), - ('Death Mountain Return Cave Exit (West)', 'West Death Mountain (Bottom)'), - ('Death Mountain Return Cave Exit (East)', 'West Death Mountain (Bottom)'), - ('Bumper Cave (Bottom)', 'Old Man Cave Ledge'), - ('Bumper Cave (Top)', 'Dark Death Mountain Healer Fairy'), - ('Bumper Cave Exit (Top)', 'Mountain Entry Ledge'), - ('Bumper Cave Exit (Bottom)', 'Mountain Entry Entrance'), - ('Dark Death Mountain Fairy', 'Old Man Cave'), - - ('Links House', 'Big Bomb Shop'), +inverted_default_connections = [('Links House', 'Big Bomb Shop'), ('Links House Exit', 'Big Bomb Shop Area'), - ('Big Bomb Shop', 'Links House'), - ('Pyramid Exit', 'Hyrule Castle Ledge')] + ('Big Bomb Shop', 'Links House')] # non shuffled dungeons default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), diff --git a/OWEdges.py b/OWEdges.py index dd77f8e7..22c67a54 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -780,7 +780,7 @@ OWTileGroups = { 'Ice Palace Area' ] ), - ("West Mountain", "Entrance"): ( + ("Mountain Entry", "Regular"): ( [ 0x0a, 0x4a ], diff --git a/Rom.py b/Rom.py index c2b8d1d5..54d0916d 100644 --- a/Rom.py +++ b/Rom.py @@ -2471,28 +2471,6 @@ def set_inverted_mode(world, player, rom, inverted_buffer): 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 - - rom.write_byte(0xDBB73 + 0x6F, 0x07) # DDM fairy entrance to old man fetch east UW - write_int16(rom, 0x15AEE + 2*0x18, 0x00F1) # old man fetch UW to DDM fairy entrance - rom.write_byte(0x15B8C + 0x18, 0x43) - write_int16(rom, 0x15BDB + 2 * 0x18, 0x1400) - write_int16(rom, 0x15C79 + 2 * 0x18, 0x0294) - write_int16(rom, 0x15D17 + 2 * 0x18, 0x0600) - write_int16(rom, 0x15DB5 + 2 * 0x18, 0x02E8) - write_int16(rom, 0x15E53 + 2 * 0x18, 0x0678) - write_int16(rom, 0x15EF1 + 2 * 0x18, 0x0303) - write_int16(rom, 0x15F8F + 2 * 0x18, 0x0685) - rom.write_byte(0x1602D + 0x18, 0x0A) - rom.write_byte(0x1607C + 0x18, 0xF6) - write_int16(rom, 0x160CB + 2 * 0x18, 0x0000) - write_int16(rom, 0x16169 + 2 * 0x18, 0x0000) - - rom.write_byte(0xDBB73 + 0x06, 0x2E) # old man fetch east entrance to DMD west UW - write_int16(rom, 0x15AEE + 2*0x08, 0x00E6) # DMD west UW to old man fetch east entrance - if (world.mode[player] == 'inverted') != (0x0A in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): - rom.write_byte(0xDBB73 + 0x16, 0x5E) # bumper cave top entrance to DDM Fairy UW - else: - rom.write_byte(0xDBB73 + 0x2D, 0x5E) # DMD west entrance to DDM Fairy if (world.mode[player] == 'inverted') != (0x05 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) # add warp under rock if (world.mode[player] == 'inverted') != (0x07 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): @@ -2502,17 +2480,6 @@ def set_inverted_mode(world, player, rom, inverted_buffer): rom.write_bytes(0x0086E, [0x5C, 0x00, 0xA0, 0xA1]) # TR tail if world.shuffle[player] in ['vanilla']: world.fix_trock_doors[player] = True - if (world.mode[player] == 'inverted') != (0x0A in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): - if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - rom.write_byte(0xDBB73 + 0x15, 0x06) # bumper cave bottom entrance to old man fetch west UW - write_int16(rom, 0x15AEE + 2*0x17, 0x00F0) # old man fetch west UW to bumper cave bottom entrance - rom.write_byte(0xDBB73 + 0x05, 0x16) # old man fetch west entrance to bumper cave bottom UW - write_int16(rom, 0x15AEE + 2*0x07, 0x00FB) # bumper cave bottom UW to old man fetch west entrance - rom.write_byte(0xDBB73 + 0x2D, 0x17) # DMD west entrance to bumper cave top UW - write_int16(rom, 0x15AEE + 2*0x2F, 0x00EB) # bumper cave top UW to DMD west entrance - if (world.mode[player] == 'inverted') == (0x03 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): - rom.write_byte(0xDBB73 + 0x16, 0x2E) # bumper cave top entrance to DMD west UW - write_int16(rom, 0x15AEE + 2*0x18, 0x00E6) # DMD west UW to bumper cave top entrance if (world.mode[player] == 'inverted') != (0x10 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): rom.write_bytes(snes_to_pc(0x1BC67A), [0x2E, 0x0B, 0x82]) # add warp under rock if (world.mode[player] == 'inverted') != (0x1B in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): @@ -2603,21 +2570,6 @@ def set_inverted_mode(world, player, rom, inverted_buffer): write_int16(rom, 0xDB96F + 2 * 0x35, 0x001B) # move pyramid exit door write_int16(rom, 0xDBA71 + 2 * 0x35, 0x011C) - rom.write_byte(0xDBB73 + 0x35, 0x36) - - write_int16(rom, 0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area - rom.write_byte(0x15B8C + 0x37, 0x1B) - write_int16(rom, 0x15BDB + 2 * 0x37, 0x000E) - write_int16(rom, 0x15C79 + 2 * 0x37, 0x0600) - write_int16(rom, 0x15D17 + 2 * 0x37, 0x0676) - write_int16(rom, 0x15DB5 + 2 * 0x37, 0x0604) - write_int16(rom, 0x15E53 + 2 * 0x37, 0x06E8) - write_int16(rom, 0x15EF1 + 2 * 0x37, 0x066D) - write_int16(rom, 0x15F8F + 2 * 0x37, 0x06F3) - rom.write_byte(0x1602D + 0x37, 0x00) - rom.write_byte(0x1607C + 0x37, 0x0A) - write_int16(rom, 0x160CB + 2 * 0x37, 0x0000) - write_int16(rom, 0x16169 + 2 * 0x37, 0x811C) if (world.mode[player] == 'inverted') != (0x29 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact if (world.mode[player] == 'inverted') != (0x2C in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): From b5aae926e71a5687f31d60fac1022d4761ba0010 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 13 Jul 2021 13:19:14 -0700 Subject: [PATCH 08/21] Minor baserom updates --- Main.py | 2 +- RELEASENOTES.md | 3 +++ Rom.py | 2 +- data/base2current.bps | Bin 136227 -> 136227 bytes 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Main.py b/Main.py index 73b60974..eb8380f3 100644 --- a/Main.py +++ b/Main.py @@ -27,7 +27,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.4.0.10u' +__version__ = '0.4.0.11u' class EnemizerError(RuntimeError): diff --git a/RELEASENOTES.md b/RELEASENOTES.md index d55904b8..cafdb92f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -22,6 +22,9 @@ For accessibility, you now get a C or P indicator to the left of the magic bar o # Bug Fixes and Notes. +* 0.4.0.11 + * Some minor base rom fixes + * Improved distribution of bombable/dashable doors * 0.4.0.10 * Renamed to pseudoboots * Some release note updates diff --git a/Rom.py b/Rom.py index 6c351828..1bdf1a59 100644 --- a/Rom.py +++ b/Rom.py @@ -30,7 +30,7 @@ from EntranceShuffle import door_addresses, exit_ids JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'df3386b7a48d79950a1432b8bbaafde1' +RANDOMIZERBASEHASH = '669813697df6a132611f4c7a008ebaae' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 2ef0bf7d96739707083688cc6cdd7ae30569487b..9d4ad8e3765029bdbeb086dd921deed9a10a87d3 100644 GIT binary patch delta 5204 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 From bd60c3f1c09ca083da952096f5c11a6684014812 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 14 Jul 2021 14:30:02 -0500 Subject: [PATCH 09/21] Split Tile Groups to reference new Tile Regions object --- OWEdges.py | 708 ++++++++++++++++++++++++++------------------ OverworldShuffle.py | 22 +- 2 files changed, 436 insertions(+), 294 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index 22c67a54..04ba3e69 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -669,477 +669,613 @@ OWEdgeGroups = { ) } +OWTileRegions = { + 0x00: [ + 'Lost Woods West Area', + 'Lost Woods East Area' + ], + 0x02: [ + 'Lumberjack Area' + ], + 0x03: [ + 'West Death Mountain (Top)', + 'Spectacle Rock Ledge', + 'West Death Mountain (Bottom)' + ], + 0x05: [ + 'Death Mountain Floating Island', + 'East Death Mountain (Top West)', + 'East Death Mountain (Top East)', + 'Spiral Cave Ledge', + 'Mimic Cave Ledge', + 'Fairy Ascension Ledge', + 'Fairy Ascension Plateau', + 'East Death Mountain (Bottom Left)', + 'East Death Mountain (Bottom)' + ], + 0x07: [ + 'Death Mountain TR Pegs', + 'Death Mountain TR Pegs Ledge' + ], + 0x0a: [ + 'Mountain Entry Area', + 'Mountain Entry Entrance', + 'Mountain Entry Ledge' + ], + 0x0f: [ + 'Zora Waterfall Area', + 'Zora Waterfall Water', + 'Waterfall of Wishing Cave' + ], + 0x10: [ + 'Lost Woods Pass West Area', + 'Lost Woods Pass East Top Area', + 'Lost Woods Pass East Bottom Area' + ], + 0x11: [ + 'Kakariko Fortune Area' + ], + 0x12: [ + 'Kakariko Pond Area' + ], + 0x13: [ + 'Sanctuary Area', + 'Bonk Rock Ledge' + ], + 0x14: [ + 'Graveyard Area', + 'Graveyard Ledge', + 'Kings Grave Area' + ], + 0x15: [ + 'River Bend Area', + 'River Bend East Bank', + 'River Bend Water' + ], + 0x16: [ + 'Potion Shop Area', + 'Potion Shop Northeast', + 'Potion Shop Water' + ], + 0x17: [ + 'Zora Approach Area', + 'Zora Approach Ledge', + 'Zora Approach Water' + ], + 0x18: [ + 'Kakariko Area', + 'Kakariko Southwest', + 'Kakariko Grass Yard' + ], + 0x1a: [ + 'Forgotten Forest Area' + ], + 0x1b: [ + 'Hyrule Castle Area', + 'Hyrule Castle Southwest', + 'Hyrule Castle Courtyard', + 'Hyrule Castle Courtyard Northeast', + 'Hyrule Castle Ledge', + 'Hyrule Castle East Entry' + ], + 0x1d: [ + 'Wooden Bridge Area', + 'Wooden Bridge Northeast', + 'Wooden Bridge Water' + ], + 0x1e: [ + 'Eastern Palace Area' + ], + 0x22: [ + 'Blacksmith Area', + 'Bat Cave Ledge' + ], + 0x25: [ + 'Sand Dunes Area' + ], + 0x28: [ + 'Maze Race Area', + 'Maze Race Ledge', + 'Maze Race Prize' + ], + 0x29: [ + 'Kakariko Suburb Area' + ], + 0x2a: [ + 'Flute Boy Area', + 'Flute Boy Pass' + ], + 0x2b: [ + 'Central Bonk Rocks Area' + ], + 0x2c: [ + 'Links House Area' + ], + 0x2d: [ + 'Stone Bridge Area', + 'Stone Bridge Water' + ], + 0x2e: [ + 'Tree Line Area', + 'Tree Line Water' + ], + 0x2f: [ + 'Eastern Nook Area' + ], + 0x30: [ + 'Desert Area', + 'Desert Ledge', + 'Desert Palace Entrance (North) Spot', + 'Desert Checkerboard Ledge', + 'Desert Palace Stairs', + 'Desert Palace Mouth', + 'Desert Palace Teleporter Ledge', + 'Bombos Tablet Ledge' + ], + 0x32: [ + 'Flute Boy Approach Area', + 'Flute Boy Bush Entry', + 'Cave 45 Ledge' + ], + 0x33: [ + 'C Whirlpool Area', + 'C Whirlpool Water', + 'C Whirlpool Outer Area' + ], + 0x34: [ + 'Statues Area', + 'Statues Water' + ], + 0x35: [ + 'Lake Hylia Area', + 'Lake Hylia South Shore', + 'Lake Hylia Northeast Bank', + 'Lake Hylia Central Island', + 'Lake Hylia Island', + 'Lake Hylia Water' + ], + 0x37: [ + 'Ice Cave Area' + ], + 0x3a: [ + 'Desert Pass Area', + 'Desert Pass Southeast', + 'Desert Pass Ledge' + ], + 0x3b: [ + 'Dam Area' + ], + 0x3c: [ + 'South Pass Area' + ], + 0x3f: [ + 'Octoballoon Area', + 'Octoballoon Water', + 'Octoballoon Water Ledge' + ], + 0x40: [ + 'Skull Woods Forest', + 'Skull Woods Portal Entry', + 'Skull Woods Forest (West)', + 'Skull Woods Forgotten Path (Southwest)', + 'Skull Woods Forgotten Path (Northeast)' + ], + 0x42: [ + 'Dark Lumberjack Area' + ], + 0x43: [ + 'West Dark Death Mountain (Top)', + 'GT Approach', + 'West Dark Death Mountain (Bottom)' + ], + 0x45: [ + 'East Dark Death Mountain (Top)', + 'East Dark Death Mountain (Bottom Left)', + 'East Dark Death Mountain (Bottom)' + ], + 0x47: [ + 'Turtle Rock Area', + 'Turtle Rock Ledge' + ], + 0x4a: [ + 'Bumper Cave Area', + 'Bumper Cave Entrance', + 'Bumper Cave Ledge' + ], + 0x4f: [ + 'Catfish Area' + ], + 0x50: [ + 'Skull Woods Pass West Area', + 'Skull Woods Pass East Top Area', + 'Skull Woods Pass East Bottom Area' + ], + 0x51: [ + 'Dark Fortune Area' + ], + 0x52: [ + 'Outcast Pond Area' + ], + 0x53: [ + 'Dark Chapel Area' + ], + 0x54: [ + 'Dark Graveyard Area' + ], + 0x55: [ + 'Qirn Jump Area', + 'Qirn Jump East Bank', + 'Qirn Jump Water' + ], + 0x56: [ + 'Dark Witch Area', + 'Dark Witch Northeast', + 'Dark Witch Water' + ], + 0x57: [ + 'Catfish Approach Area', + 'Catfish Approach Ledge', + 'Catfish Approach Water' + ], + 0x58: [ + 'Village of Outcasts Area', + 'Dark Grassy Lawn' + ], + 0x5a: [ + 'Shield Shop Area', + 'Shield Shop Fence' + ], + 0x5b: [ + 'Pyramid Area', + 'Pyramid Exit Ledge', + 'Pyramid Pass' + ], + 0x5d: [ + 'Broken Bridge Area', + 'Broken Bridge Northeast', + 'Broken Bridge West', + 'Broken Bridge Water' + ], + 0x5e: [ + 'Palace of Darkness Area' + ], + 0x62: [ + 'Hammer Pegs Area', + 'Hammer Pegs Entry' + ], + 0x65: [ + 'Dark Dunes Area' + ], + 0x68: [ + 'Dig Game Area', + 'Dig Game Ledge' + ], + 0x69: [ + 'Frog Area', + 'Frog Prison', + 'Archery Game Area' + ], + 0x6a: [ + 'Stumpy Area', + 'Stumpy Pass' + ], + 0x6b: [ + 'Dark Bonk Rocks Area' + ], + 0x6c: [ + 'Big Bomb Shop Area' + ], + 0x6d: [ + 'Hammer Bridge North Area', + 'Hammer Bridge South Area', + 'Hammer Bridge Water' + ], + 0x6e: [ + 'Dark Tree Line Area', + 'Dark Tree Line Water' + ], + 0x6f: [ + 'Palace of Darkness Nook Area' + ], + 0x70: [ + 'Misery Mire Area', + 'Misery Mire Teleporter Ledge' + ], + 0x72: [ + 'Stumpy Approach Area', + 'Stumpy Approach Bush Entry' + ], + 0x73: [ + 'Dark C Whirlpool Area', + 'Dark C Whirlpool Water', + 'Dark C Whirlpool Outer Area' + ], + 0x74: [ + 'Hype Cave Area', + 'Hype Cave Water' + ], + 0x75: [ + 'Ice Lake Area', + 'Ice Lake Northeast Bank', + 'Ice Lake Ledge (West)', + 'Ice Lake Ledge (East)', + 'Ice Lake Water', + 'Ice Lake Moat', + 'Ice Palace Area' + ], + 0x77: [ + 'Shopping Mall Area' + ], + 0x7a: [ + 'Swamp Nook Area' + ], + 0x7b: [ + 'Swamp Area' + ], + 0x7c: [ + 'Dark South Pass Area' + ], + 0x7f: [ + 'Bomber Corner Area', + 'Bomber Corner Water', + 'Bomber Corner Water Ledge' + ], + 0x80: [ + 'Master Sword Meadow', + 'Hobo Bridge' + ], + 0x81: [ + 'Zoras Domain' + ] +} + OWTileGroups = { ("Woods", "Regular"): ( [ - 0x00, 0x2d, 0x40, 0x6d, 0x80 + 0x00, 0x2d, 0x80 ], [ - 'Master Sword Meadow', - 'Lost Woods West Area', - 'Lost Woods East Area', - 'Stone Bridge Area', - 'Stone Bridge Water', - 'Hobo Bridge' - ], - [ - 'Skull Woods Forest', - 'Skull Woods Portal Entry', - 'Skull Woods Forest (West)', - 'Skull Woods Forgotten Path (Southwest)', - 'Skull Woods Forgotten Path (Northeast)', - 'Hammer Bridge North Area', - 'Hammer Bridge South Area', - 'Hammer Bridge Water' + 0x40, 0x6d ] ), ("Lumberjack", "Regular"): ( [ - 0x02, 0x42 + 0x02 ], [ - 'Lumberjack Area' - ], - [ - 'Dark Lumberjack Area' + 0x42 ] ), ("West Mountain", "Regular"): ( [ - 0x03, 0x43 + 0x03 ], [ - 'West Death Mountain (Top)', - 'Spectacle Rock Ledge', - 'West Death Mountain (Bottom)' - ], - [ - 'West Dark Death Mountain (Top)', - 'GT Approach', - 'West Dark Death Mountain (Bottom)' + 0x43 ] ), ("East Mountain", "Regular"): ( [ - 0x05, 0x45 + 0x05 ], [ - 'Death Mountain Floating Island', - 'East Death Mountain (Top West)', - 'East Death Mountain (Top East)', - 'Spiral Cave Ledge', - 'Mimic Cave Ledge', - 'Fairy Ascension Ledge', - 'Fairy Ascension Plateau', - 'East Death Mountain (Bottom Left)', - 'East Death Mountain (Bottom)' - ], - [ - 'East Dark Death Mountain (Top)', - 'East Dark Death Mountain (Bottom Left)', - 'East Dark Death Mountain (Bottom)' + 0x45 ] ), ("East Mountain", "Entrance"): ( [ - 0x07, 0x47 + 0x07, ], [ - 'Death Mountain TR Pegs', - 'Death Mountain TR Pegs Ledge' - ], - [ - 'Turtle Rock Area', - 'Turtle Rock Ledge' + 0x47 ] ), ("Lake", "Regular"): ( [ - 0x0f, 0x35, 0x4f, 0x75, 0x81 + 0x0f, 0x35, 0x81 ], [ - 'Zora Waterfall Area', - 'Zora Waterfall Water', - 'Waterfall of Wishing Cave', - 'Zoras Domain', - 'Lake Hylia Area', - 'Lake Hylia South Shore', - 'Lake Hylia Northeast Bank', - 'Lake Hylia Central Island', - 'Lake Hylia Island', - 'Lake Hylia Water' - ], - [ - 'Catfish Area', - 'Ice Lake Area', - 'Ice Lake Northeast Bank', - 'Ice Lake Ledge (West)', - 'Ice Lake Ledge (East)', - 'Ice Lake Water', - 'Ice Lake Moat', - 'Ice Palace Area' + 0x4f, 0x75 ] ), ("Mountain Entry", "Regular"): ( [ - 0x0a, 0x4a + 0x0a ], [ - 'Mountain Entry Area', - 'Mountain Entry Entrance', - 'Mountain Entry Ledge' - ], - [ - 'Bumper Cave Area', - 'Bumper Cave Entrance', - 'Bumper Cave Ledge' + 0x4a ] ), ("Woods Pass", "Regular"): ( [ - 0x10, 0x50 + 0x10 ], [ - 'Lost Woods Pass West Area', - 'Lost Woods Pass East Top Area', - 'Lost Woods Pass East Bottom Area' - ], - [ - 'Skull Woods Pass West Area', - 'Skull Woods Pass East Top Area', - 'Skull Woods Pass East Bottom Area' + 0x50 ] ), ("Fortune", "Regular"): ( [ - 0x11, 0x51 + 0x11 ], [ - 'Kakariko Fortune Area' - ], - [ - 'Dark Fortune Area' + 0x51 ] ), ("Whirlpools", "Regular"): ( [ - 0x12, 0x15, 0x33, 0x3f, 0x52, 0x55, 0x73, 0x7f + 0x12, 0x15, 0x33, 0x3f ], [ - 'Kakariko Pond Area', - 'River Bend Area', - 'River Bend East Bank', - 'River Bend Water', - 'C Whirlpool Area', - 'C Whirlpool Water', - 'C Whirlpool Outer Area', - 'Octoballoon Area', - 'Octoballoon Water', - 'Octoballoon Water Ledge' - ], - [ - 'Outcast Pond Area', - 'Qirn Jump Area', - 'Qirn Jump East Bank', - 'Qirn Jump Water', - 'Dark C Whirlpool Area', - 'Dark C Whirlpool Water', - 'Dark C Whirlpool Outer Area', - 'Bomber Corner Area', - 'Bomber Corner Water', - 'Bomber Corner Water Ledge' + 0x52, 0x55, 0x73, 0x7f ] ), ("Castle", "Entrance"): ( [ - 0x13, 0x14, 0x53, 0x54 + 0x13, 0x14 ], [ - 'Sanctuary Area', - 'Bonk Rock Ledge', - 'Graveyard Area', - 'Graveyard Ledge', - 'Kings Grave Area' - ], - [ - 'Dark Chapel Area', - 'Dark Graveyard Area' + 0x53, 0x54 ] ), ("Castle", "Regular"): ( [ - 0x1a, 0x1b, 0x5a, 0x5b + 0x1a, 0x1b ], [ - 'Forgotten Forest Area', - 'Hyrule Castle Area', - 'Hyrule Castle Southwest', - 'Hyrule Castle Courtyard', - 'Hyrule Castle Courtyard Northeast', - 'Hyrule Castle Ledge', - 'Hyrule Castle East Entry' - ], - [ - 'Shield Shop Area', - 'Shield Shop Fence', - 'Pyramid Area', - 'Pyramid Exit Ledge', - 'Pyramid Pass' + 0x5a, 0x5b ] ), ("Witch", "Regular"): ( [ - 0x16, 0x56 + 0x16 ], [ - 'Potion Shop Area', - 'Potion Shop Northeast', - 'Potion Shop Water' - ], - [ - 'Dark Witch Area', - 'Dark Witch Northeast', - 'Dark Witch Water' + 0x56 ] ), ("Water Approach", "Regular"): ( [ - 0x17, 0x57 + 0x17 ], [ - 'Zora Approach Area', - 'Zora Approach Ledge', - 'Zora Approach Water' - ], - [ - 'Catfish Approach Area', - 'Catfish Approach Ledge', - 'Catfish Approach Water' + 0x57 ] ), ("Village", "Regular"): ( [ - 0x18, 0x58 + 0x18 ], [ - 'Kakariko Area', - 'Kakariko Southwest', - 'Kakariko Grass Yard' - ], - [ - 'Village of Outcasts Area', - 'Dark Grassy Lawn' + 0x58 ] ), ("Wooden Bridge", "Regular"): ( [ - 0x1d, 0x5d + 0x1d ], [ - 'Wooden Bridge Area', - 'Wooden Bridge Northeast', - 'Wooden Bridge Water' - ], - [ - 'Broken Bridge Area', - 'Broken Bridge Northeast', - 'Broken Bridge West', - 'Broken Bridge Water' + 0x5d ] ), ("Eastern", "Regular"): ( [ - 0x1e, 0x5e + 0x1e ], [ - 'Eastern Palace Area' - ], - [ - 'Palace of Darkness Area' + 0x5e ] ), ("Blacksmith", "Regular"): ( [ - 0x22, 0x62 + 0x22 ], [ - 'Blacksmith Area', - 'Bat Cave Ledge' - ], - [ - 'Hammer Pegs Area', - 'Hammer Pegs Entry' + 0x62 ] ), ("Dunes", "Regular"): ( [ - 0x25, 0x65 + 0x25 ], [ - 'Sand Dunes Area' - ], - [ - 'Dark Dunes Area' + 0x65 ] ), ("Game", "Regular"): ( [ - 0x28, 0x29, 0x68, 0x69 + 0x28, 0x29 ], [ - 'Maze Race Area', - 'Maze Race Ledge', - 'Maze Race Prize', - 'Kakariko Suburb Area' - ], - [ - 'Dig Game Area', - 'Dig Game Ledge', - 'Frog Area', - 'Frog Prison', - 'Archery Game Area' + 0x68, 0x69 ] ), ("Grove", "Regular"): ( [ - 0x2a, 0x6a + 0x2a ], [ - 'Flute Boy Area', - 'Flute Boy Pass' - ], - [ - 'Stumpy Area', - 'Stumpy Pass' + 0x6a ] ), ("Central Bonk Rocks", "Regular"): ( [ - 0x2b, 0x6b + 0x2b ], [ - 'Central Bonk Rocks Area' - ], - [ - 'Dark Bonk Rocks Area' + 0x6b ] ), # ("Links", "Regular"): ( # [ - # 0x2c, 0x6c + # 0x2c # ], # [ - # 'Links House Area' - # ], - # [ - # 'Big Bomb Shop Area' + # 0x6c # ] # ), ("Tree Line", "Regular"): ( [ - 0x2e, 0x6e + 0x2e ], [ - 'Tree Line Area', - 'Tree Line Water' - ], - [ - 'Dark Tree Line Area', - 'Dark Tree Line Water' + 0x6e ] ), ("Nook", "Regular"): ( [ - 0x2f, 0x6f + 0x2f ], [ - 'Eastern Nook Area' - ], - [ - 'Palace of Darkness Nook Area' + 0x6f ] ), ("Desert", "Regular"): ( [ - 0x30, 0x3a, 0x70, 0x7a + 0x30, 0x3a ], [ - 'Desert Area', - 'Desert Ledge', - 'Desert Palace Entrance (North) Spot', - 'Desert Checkerboard Ledge', - 'Desert Palace Stairs', - 'Desert Palace Mouth', - 'Desert Palace Teleporter Ledge', - 'Bombos Tablet Ledge', - 'Desert Pass Area', - 'Desert Pass Southeast', - 'Desert Pass Ledge' - ], - [ - 'Misery Mire Area', - 'Misery Mire Teleporter Ledge', - 'Swamp Nook Area' + 0x70, 0x7a ] ), ("Grove Approach", "Regular"): ( [ - 0x32, 0x72 + 0x32 ], [ - 'Flute Boy Approach Area', - 'Flute Boy Bush Entry', - 'Cave 45 Ledge' - ], - [ - 'Stumpy Approach Area', - 'Stumpy Approach Bush Entry' + 0x72 ] ), ("Hype", "Regular"): ( [ - 0x34, 0x74 + 0x34 ], [ - 'Statues Area', - 'Statues Water' - ], - [ - 'Hype Cave Area', - 'Hype Cave Water' + 0x74 ] ), ("Shopping Mall", "Regular"): ( [ - 0x37, 0x77 + 0x37 ], [ - 'Ice Cave Area' - ], - [ - 'Shopping Mall Area' + 0x77 ] ), ("Swamp", "Regular"): ( [ - 0x3b, 0x7b + 0x3b ], [ - 'Dam Area' - ], - [ - 'Swamp Area' + 0x7b ] ), ("South Pass", "Regular"): ( [ - 0x3c, 0x7c + 0x3c ], [ - 'South Pass Area' - ], - [ - 'Dark South Pass Area' + 0x7c ] ) } diff --git a/OverworldShuffle.py b/OverworldShuffle.py index f1199212..71641fbe 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1,6 +1,6 @@ import random, logging, copy from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSlot -from OWEdges import OWTileGroups, OWEdgeGroups, OpenStd, parallel_links, IsParallel +from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OpenStd, parallel_links, IsParallel try: from sortedcontainers import SortedList except ImportError: @@ -28,18 +28,24 @@ def link_overworld(world, player): for (name, groupType) in OWTileGroups.keys(): if world.mode[player] != 'standard' or name not in ['Castle', 'Links', 'Central Bonk Rocks']: - (owids, lw_regions, dw_regions) = OWTileGroups[(name, groupType,)] + (lw_owids, dw_owids) = OWTileGroups[(name, groupType,)] if world.shuffle[player] in ['vanilla', 'simple', 'dungeonssimple']: (exist_owids, exist_lw_regions, exist_dw_regions) = tile_groups[(name,)] - exist_owids.extend(owids) - exist_lw_regions.extend(lw_regions) - exist_dw_regions.extend(dw_regions) + exist_owids.extend(lw_owids) + exist_owids.extend(dw_owids) + for owid in lw_owids: + exist_lw_regions.extend(OWTileRegions[owid]) + for owid in dw_owids: + exist_dw_regions.extend(OWTileRegions[owid]) tile_groups[(name,)] = (exist_owids, exist_lw_regions, exist_dw_regions) else: (exist_owids, exist_lw_regions, exist_dw_regions) = tile_groups[(name, groupType)] - exist_owids.extend(owids) - exist_lw_regions.extend(lw_regions) - exist_dw_regions.extend(dw_regions) + exist_owids.extend(lw_owids) + exist_owids.extend(dw_owids) + for owid in lw_owids: + exist_lw_regions.extend(OWTileRegions[owid]) + for owid in dw_owids: + exist_dw_regions.extend(OWTileRegions[owid]) tile_groups[(name, groupType)] = (exist_owids, exist_lw_regions, exist_dw_regions) #tile shuffle happens here, the groups that remain in the list are the tiles that get swapped From a123661eca76f635324c09f8e6a36c7f85a2c89c Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 15 Jul 2021 10:32:25 -0700 Subject: [PATCH 10/21] Don't fix ugly smalls in vanilla --- DoorShuffle.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index b3f8cb5e..2e6f8b44 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -100,8 +100,8 @@ def link_doors_main(world, player): analyze_portals(world, player) for portal in world.dungeon_portals[player]: connect_portal(portal, world, player) - - fix_big_key_doors_with_ugly_smalls(world, player) + if not world.doorShuffle[player] == 'vanilla': + fix_big_key_doors_with_ugly_smalls(world, player) if world.doorShuffle[player] == 'vanilla': for entrance, ext in open_edges: connect_two_way(world, entrance, ext, player) From 06486e88a2dbc200c99357c4fb0a16dc96d45b93 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 15 Jul 2021 10:33:04 -0700 Subject: [PATCH 11/21] Cutoff rug addition --- Rom.py | 2 +- asm/doortables.asm | 4 ++-- data/base2current.bps | Bin 136227 -> 136225 bytes 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Rom.py b/Rom.py index 1bdf1a59..5c61e5c2 100644 --- a/Rom.py +++ b/Rom.py @@ -30,7 +30,7 @@ from EntranceShuffle import door_addresses, exit_ids JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '669813697df6a132611f4c7a008ebaae' +RANDOMIZERBASEHASH = '25dd18672e1234c85900f5b2155e7e4f' class JsonRom(object): diff --git a/asm/doortables.asm b/asm/doortables.asm index db1b6711..8ee0dd60 100644 --- a/asm/doortables.asm +++ b/asm/doortables.asm @@ -580,8 +580,8 @@ dw $00bc, $00a2, $00a3, $00c2, $001a, $0049, $0014, $008c ; Ice Many Pots, Swamp Waterfall, GT Gauntlet 3, Eastern Push Block, Eastern Courtyard, Eastern Map Valley ; Eastern Cannonball, HC East Hall dw $009f, $0066, $005d, $00a8, $00a9, $00aa, $00b9, $0052 -; HC West Hall, TR Dash Bridge, TR Hub, Pod Arena, GT Petting Zoo -dw $0050, $00c5, $00c6, $0009, $0003, $002a, $007d +; HC West Hall, TR Dash Bridge, TR Hub, Pod Arena, GT Petting Zoo, Ice Spike Cross +dw $0050, $00c5, $00c6, $0009, $0003, $002a, $007d, $005e dw $ffff ; dungeon tables diff --git a/data/base2current.bps b/data/base2current.bps index 9d4ad8e3765029bdbeb086dd921deed9a10a87d3..53bd7d8680aa4516815cb90e352fe3ea90cbc137 100644 GIT binary patch delta 53 zcmV-50LuTPs0g8`2(Ur{1l?dFpR+~*;rj@Z2Bx L+12*e5Zv);rj|NhAI=48}|`Ufs-%&A_8ANgH!#tQ~d$P N76@kAM>B8q$^myo7aITo From 2e60b374a658a5cdd0122f42aa09e89aa551b1e4 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Fri, 16 Jul 2021 22:36:33 +1000 Subject: [PATCH 12/21] Copy owswaps so that the world used to generate the playthrough has correct logic. --- Main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Main.py b/Main.py index 74484b68..0de80926 100644 --- a/Main.py +++ b/Main.py @@ -399,6 +399,7 @@ def copy_world(world): ret.keydropshuffle = world.keydropshuffle.copy() ret.mixed_travel = world.mixed_travel.copy() ret.standardize_palettes = world.standardize_palettes.copy() + ret.owswaps = world.owswaps.copy() for player in range(1, world.players + 1): create_regions(ret, player) From 94a1c3ad1cab9979cbb49e71d552e7c1c8f3fe2f Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 16 Jul 2021 12:09:45 -0500 Subject: [PATCH 13/21] Fixed spoiler log to show more detail for Flute Shuffle --- BaseClasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index 60cc1c74..a0609460 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2244,7 +2244,7 @@ class Spoiler(object): outfile.write('Overworld Tile Swap:'.ljust(line_width) + '%s\n' % self.metadata['ow_swap'][player]) if self.metadata['ow_shuffle'][player] != 'vanilla': outfile.write('Keep Similar OW Edges Together:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_keepsimilar'][player] else 'No')) - outfile.write('Flute Shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_fluteshuffle'][player] != 'vanilla' else 'No')) + outfile.write('Flute Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_fluteshuffle'][player]) outfile.write('Entrance Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['shuffle'][player]) outfile.write('Door Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['door_shuffle'][player]) outfile.write('Intensity:'.ljust(line_width) + '%s\n' % self.metadata['intensity'][player]) From 5cf0274aac4771ec2ef42d1127a53905705a76ec Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 16 Jul 2021 12:41:25 -0500 Subject: [PATCH 14/21] Added flute spots to world copy --- Main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Main.py b/Main.py index 0de80926..f1d90bb4 100644 --- a/Main.py +++ b/Main.py @@ -400,6 +400,7 @@ def copy_world(world): ret.mixed_travel = world.mixed_travel.copy() ret.standardize_palettes = world.standardize_palettes.copy() ret.owswaps = world.owswaps.copy() + ret.owflutespots = world.owflutespots.copy() for player in range(1, world.players + 1): create_regions(ret, player) From dd2b7effcb0a7aff9b92f0b568d6423948173085 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 16 Jul 2021 12:42:14 -0500 Subject: [PATCH 15/21] Fixed AT/GT rules to follow Mode instead of OW Swap --- Rules.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Rules.py b/Rules.py index 2b263c38..d26a861b 100644 --- a/Rules.py +++ b/Rules.py @@ -837,6 +837,13 @@ def default_rules(world, player): def ow_rules(world, player): + if world.mode[player] != 'inverted': + 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', 'crossed', 'insanity')) + else: + set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) + if (world.mode[player] == 'inverted') == (0x00 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): set_rule(world.get_entrance('Lost Woods East Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Lost Woods Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) @@ -858,9 +865,6 @@ def ow_rules(world, player): set_rule(world.get_entrance('Dark Lumberjack Mirror Spot', player), lambda state: state.has_Mirror(player)) if (world.mode[player] == 'inverted') == (0x03 in world.owswaps[player][0] and world.owSwap[player] == 'mixed'): - 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', 'crossed', 'insanity')) - set_rule(world.get_entrance('West Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Spectacle Rock Mirror Spot', player), lambda state: state.has_Mirror(player)) else: @@ -991,7 +995,6 @@ def ow_rules(world, player): set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: False) set_rule(world.get_entrance('Inverted Pyramid Entrance', player), lambda state: False) set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) - 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('HC Area Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('HC Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) @@ -1004,7 +1007,6 @@ def ow_rules(world, player): set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) add_rule(world.get_entrance('Pyramid Hole', player), lambda state: False) set_rule(world.get_entrance('Pyramid Entrance', player), lambda state: False) - set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) set_rule(world.get_entrance('Pyramid Exit Ledge Drop', player), lambda state: state.has('Hammer', player)) set_rule(world.get_entrance('Pyramid Mirror Spot', player), lambda state: state.has_Mirror(player)) From 29039fef91b97fb448ee938f4c7e90c9f0ce603f Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 16 Jul 2021 12:43:08 -0500 Subject: [PATCH 16/21] Moved Inverted specific entrances to mode-specific list --- EntranceShuffle.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index f73f0ea3..d4449cd8 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -2873,10 +2873,6 @@ default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'), ('Hookshot Cave Back Entrance', 'Hookshot Cave'), ('Mimic Cave', 'Mimic Cave'), - ('Pyramid Hole', 'Pyramid'), - ('Pyramid Entrance', 'Bottom of Pyramid'), - ('Inverted Pyramid Hole', 'Pyramid'), - ('Inverted Pyramid Entrance', 'Bottom of Pyramid'), ('Pyramid Exit', 'Pyramid Exit Ledge') ] @@ -2899,11 +2895,17 @@ swapped_connections = { open_default_connections = [('Links House', 'Links House'), ('Links House Exit', 'Links House Area'), - ('Big Bomb Shop', 'Big Bomb Shop')] + ('Big Bomb Shop', 'Big Bomb Shop'), + ('Pyramid Hole', 'Pyramid'), + ('Pyramid Entrance', 'Bottom of Pyramid') + ] inverted_default_connections = [('Links House', 'Big Bomb Shop'), ('Links House Exit', 'Big Bomb Shop Area'), - ('Big Bomb Shop', 'Links House')] + ('Big Bomb Shop', 'Links House'), + ('Inverted Pyramid Hole', 'Pyramid'), + ('Inverted Pyramid Entrance', 'Bottom of Pyramid') + ] # non shuffled dungeons default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), From e31af840cc76b28076dec1f845009f0d7eb26bac Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 16 Jul 2021 12:51:44 -0500 Subject: [PATCH 17/21] Added minor commented data as prep --- OWEdges.py | 18 ++++++++++++++++++ OverworldShuffle.py | 5 ++++- asm/owrando.asm | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index 04ba3e69..3d3a4bd9 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -437,6 +437,16 @@ OWEdgeGroups = { ['Octoballoon NE'] ] ), + # (Op, LW, Vt, Ld, NP, 1): ( + # [ + # ['Master Sword Meadow SC'], + # ['Zoras Domain SW'] + # ], + # [ + # ['Lost Woods NW'], + # ['Zora Waterfall NE'] + # ] + # ), (Op, LW, Hz, Ld, PL, 2): ( [ ['Kakariko Fortune EN', 'Kakariko Fortune ES'], @@ -493,6 +503,14 @@ OWEdgeGroups = { ['Statues WC'] ] ), + # (Op, LW, Hz, Wr, NP, 1): ( + # [ + # ['Hobo EC'] + # ], + # [ + # ['Stone Bridge WC'] + # ] + # ), (Op, LW, Vt, Wr, PL, 1): ( [ ['Tree Line SC'], diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 71641fbe..6c87cc04 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1092,12 +1092,14 @@ parallelsimilar_connections = [('Maze Race ES', 'Kakariko Suburb WS'), ] # non shuffled overworld -default_connections = [('Lost Woods SW', 'Lost Woods Pass NW'), +default_connections = [#('Lost Woods NW', 'Master Sword Meadow SC'), + ('Lost Woods SW', 'Lost Woods Pass NW'), ('Lost Woods SC', 'Lost Woods Pass NE'), ('Lost Woods SE', 'Kakariko Fortune NE'), ('Lost Woods EN', 'Lumberjack WN'), ('Lumberjack SW', 'Mountain Entry NW'), ('Mountain Entry SE', 'Kakariko Pond NE'), + #('Zora Waterfall NE', 'Zoras Domain SW'), ('Lost Woods Pass SW', 'Kakariko NW'), ('Lost Woods Pass SE', 'Kakariko NC'), ('Kakariko Fortune SC', 'Kakariko NE'), @@ -1146,6 +1148,7 @@ default_connections = [('Lost Woods SW', 'Lost Woods Pass NW'), ('Stone Bridge SC', 'Lake Hylia NW'), ('Stone Bridge EN', 'Tree Line WN'), ('Stone Bridge EC', 'Tree Line WC'), + #('Stone Bridge WC', 'Hobo EC'), ('Tree Line SC', 'Lake Hylia NC'), ('Tree Line SE', 'Lake Hylia NE'), ('Desert EC', 'Desert Pass WC'), diff --git a/asm/owrando.asm b/asm/owrando.asm index 8cd7bcf1..e0d986f5 100644 --- a/asm/owrando.asm +++ b/asm/owrando.asm @@ -353,7 +353,7 @@ OWNewDestination: ; turn into bunny lda $5d : cmp #$17 : beq .return lda #$17 : sta $5d - lda #$01 : sta $2e0 + lda #$01 : sta $02e0 bra .return .nobunny lda $5d : cmp #$17 : bne .return From 35162a50f93f98d3559cf9229c47c5ab8143afea Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 16 Jul 2021 13:01:41 -0500 Subject: [PATCH 18/21] Version bump 0.1.6.7 --- CHANGELOG.md | 9 ++++++++- OverworldShuffle.py | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 073c97bb..110c7008 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,18 @@ # Changelog +### 0.1.6.7 +- Fixed issue with Pyramid Exit exiting to wrong location in ER +- Mountain Entry and West Death Mountain are now Swapped independently (Old Man rescue is always in your starting world) +- Fixed issue with AT/GT access logic +- Improved spoiler log playthru accuracy +- ~~Merged DR v0.4.0.11 - Various DR changes~~ + ### 0.1.6.6 - ~~Merged DR v0.4.0.9 - P/C Indicator / Credits fix / CLI Hints Fix~~ ### 0.1.6.5 - Reduced chance of diagonal flute spot in Balanced -- ~~Merged DR v0.4.0.8 - Boss Indicator / Fake Boots / Quickswap Update / Credits Updates~~ +- ~~Merged DR v0.4.0.8 - Boss Indicator / Psuedo Boots / Quickswap Update / Credits Updates~~ ### 0.1.6.4 - Fixed Frogsmith and Stumpy and restored progression in these locations diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 6c87cc04..90c1c8dc 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -6,7 +6,7 @@ try: except ImportError: raise Exception('Could not load sortedcontainers module') -__version__ = '0.1.6.6-u' +__version__ = '0.1.6.7-u' def link_overworld(world, player): # setup mandatory connections From 40546155163487778f8e4ee580ef084d59acd727 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 16 Jul 2021 15:10:34 -0500 Subject: [PATCH 19/21] Removed sortedcontainers dependency --- OverworldShuffle.py | 13 +++++-------- README.md | 2 +- resources/app/meta/manifests/pip_requirements.txt | 1 - 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 90c1c8dc..3a700045 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1,10 +1,6 @@ import random, logging, copy from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSlot from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OpenStd, parallel_links, IsParallel -try: - from sortedcontainers import SortedList -except ImportError: - raise Exception('Could not load sortedcontainers module') __version__ = '0.1.6.7-u' @@ -161,16 +157,16 @@ def link_overworld(world, player): connect_flutes(default_flute_connections) else: flute_pool = list(flute_data.keys()) - new_spots = SortedList() + new_spots = list() # guarantee desert/mire access flute_pool.remove(0x38) - new_spots.add(0x38) + new_spots.append(0x38) # guarantee mountain access mountainIds = [0x0b, 0x0e, 0x07] owslot = mountainIds[random.randint(0, 2)] flute_pool.remove(owslot) - new_spots.add(owslot) + new_spots.append(owslot) random.shuffle(flute_pool) f = 0 @@ -190,8 +186,9 @@ def link_overworld(world, player): f += 1 continue if flute_pool[f] not in new_spots: - new_spots.add(flute_pool[f]) + new_spots.append(flute_pool[f]) f += 1 + new_spots.sort() world.owflutespots[player] = new_spots connect_flutes(new_spots) diff --git a/README.md b/README.md index 0f495d1f..4f466faf 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Download the source code from the repository directly and put it in a folder of You must have Python installed (version 3.6 - 3.9 supported) -This program requires all python dependencies that are necessary to run Aerinon's Door Randomizer plus an additional 'sortedcontainers' package. Try running ```pip install sortedcontainers``` or ```python -m pip install sortedcontainers``` on the command line to install the dependency. +This program requires all python dependencies that are necessary to run Aerinon's Door Randomizer. Try running ```pip install missingdependency``` or ```python -m pip install missingdependency``` on the command line (replace ```missingdependency``` with the specific package that is missing) to install the dependency. Alternatively, run ```resources/ci/common/local_install.py``` to install all the missing dependencies as well. diff --git a/resources/app/meta/manifests/pip_requirements.txt b/resources/app/meta/manifests/pip_requirements.txt index 7b7724d8..faa3c48f 100644 --- a/resources/app/meta/manifests/pip_requirements.txt +++ b/resources/app/meta/manifests/pip_requirements.txt @@ -1,7 +1,6 @@ aenum fast-enum python-bps-continued -sortedcontainers colorama aioconsole websockets From 6bd4a656aa3f571df2a4fc0cbb0c2cdbf84a3ad8 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 16 Jul 2021 18:33:21 -0500 Subject: [PATCH 20/21] Changelog update --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 110c7008..8e1f60c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ # Changelog ### 0.1.6.7 -- Fixed issue with Pyramid Exit exiting to wrong location in ER - Mountain Entry and West Death Mountain are now Swapped independently (Old Man rescue is always in your starting world) - Fixed issue with AT/GT access logic - Improved spoiler log playthru accuracy +- Fixed Boss Music when boss room is entered thru straight stairs +- Suppressed in-dungeon music changes when DR is enabled +- Fixed issue with Pyramid Exit exiting to wrong location in ER - ~~Merged DR v0.4.0.11 - Various DR changes~~ ### 0.1.6.6 From e12fda8a26ad949d041985cf816109113dc02e4e Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 16 Jul 2021 18:34:08 -0500 Subject: [PATCH 21/21] Changelog update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e1f60c4..455a22d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Fixed Boss Music when boss room is entered thru straight stairs - Suppressed in-dungeon music changes when DR is enabled - Fixed issue with Pyramid Exit exiting to wrong location in ER +- Removed sortedcontainers dependency - ~~Merged DR v0.4.0.11 - Various DR changes~~ ### 0.1.6.6