From 6e9d949439c5df5933d19052764d85cb774365c7 Mon Sep 17 00:00:00 2001 From: Catobat <69204835+Catobat@users.noreply.github.com> Date: Mon, 13 Jun 2022 20:38:24 +0200 Subject: [PATCH] Shuffle Back of Tavern --- BaseClasses.py | 7 ++- CLI.py | 5 +- ER_hint_reference.txt | 2 + EntranceShuffle.py | 4 +- Main.py | 3 +- README.md | 5 ++ Rom.py | 6 ++- data/base2current.bps | Bin 93021 -> 93118 bytes mystery_testsuite.yml | 3 ++ resources/app/cli/args.json | 4 ++ resources/app/cli/lang/en.json | 3 ++ resources/app/gui/lang/en.json | 1 + .../app/gui/randomize/entrando/widgets.json | 1 + source/classes/CustomSettings.py | 2 + source/classes/constants.py | 1 + source/overworld/EntranceShuffle2.py | 44 ++++++++++-------- source/tools/MysteryUtils.py | 1 + 17 files changed, 64 insertions(+), 28 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 2b56d39f..fd9e0c9c 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2460,6 +2460,7 @@ class Spoiler(object): 'goal': self.world.goal, 'shuffle': self.world.shuffle, 'shufflelinks': self.world.shufflelinks, + 'shuffletavern': self.world.shuffletavern, 'door_shuffle': self.world.doorShuffle, 'intensity': self.world.intensity, 'item_pool': self.world.difficulty, @@ -2541,7 +2542,8 @@ class Spoiler(object): outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player]) outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player]) outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player]) - outfile.write(f"Link's House Shuffled: {yn(self.metadata['shufflelinks'])}\n") + outfile.write(f"Link's House Shuffled: {yn(self.metadata['shufflelinks'][player])}\n") + outfile.write(f"Back of Tavern Shuffled: {yn(self.metadata['shuffletavern'][player])}\n") outfile.write('Door Shuffle: %s\n' % self.metadata['door_shuffle'][player]) outfile.write('Intensity: %s\n' % self.metadata['intensity'][player]) outfile.write(f"Drop Shuffle: {yn(self.metadata['dropshuffle'][player])}\n") @@ -2827,7 +2829,7 @@ class Settings(object): (0x80 if w.bigkeyshuffle[p] else 0) | (0x40 if w.keyshuffle[p] else 0) | (0x20 if w.mapshuffle[p] else 0) | (0x10 if w.compassshuffle[p] else 0) - | (enemy_mode[w.enemy_shuffle[p]]), + | (0x8 if w.shuffletavern[p] else 0) | (enemy_mode[w.enemy_shuffle[p]]), (e_health[w.enemy_health[p]] << 5) | (e_dmg[w.enemy_damage[p]] << 3) | (0x4 if w.potshuffle[p] else 0) | (0x2 if w.bombbag[p] else 0) | (1 if w.shufflelinks[p] else 0), @@ -2885,6 +2887,7 @@ class Settings(object): args.mapshuffle[p] = True if settings[7] & 0x20 else False args.compassshuffle[p] = True if settings[7] & 0x10 else False # args.shufflebosses[p] = r(boss_mode)[(settings[7] & 0xc) >> 2] + args.shuffletavern[p] = True if settings[7] & 0x8 else False args.shuffleenemies[p] = r(enemy_mode)[settings[7] & 0x3] args.enemy_health[p] = r(e_health)[(settings[8] & 0xE0) >> 5] diff --git a/CLI.py b/CLI.py index c659d3b5..62fee1b3 100644 --- a/CLI.py +++ b/CLI.py @@ -119,8 +119,8 @@ def parse_cli(argv, no_defaults=False): 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', 'usestartinventory', 'bombbag', 'overworld_map', 'restrict_boss_items', 'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max', - 'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'pseudoboots', - 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', + 'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'shuffletavern', + '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', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle', @@ -170,6 +170,7 @@ def parse_settings(): "shuffleganon": True, "shuffle": "vanilla", "shufflelinks": False, + "shuffletavern": False, "overworld_map": "default", "pseudoboots": False, diff --git a/ER_hint_reference.txt b/ER_hint_reference.txt index 999fb436..018dfb3a 100644 --- a/ER_hint_reference.txt +++ b/ER_hint_reference.txt @@ -91,6 +91,7 @@ While the exact verbage of location names and item names can be found in the sou Overworld Entrance naming: +Links House: The hero's old residence Turtle Rock: Turtle Rock Main Misery Mire: Misery Mire Ice Palace: Ice Palace @@ -141,6 +142,7 @@ Lake Hylia Fairy: A cave NE of Lake Hylia Light Hype Fairy: The cave south of your house Desert Fairy: The cave near the desert Chicken House: The chicken lady's house +Tavern North: A backdoor Aginahs Cave: The open desert cave Sahasrahlas Hut: The house near armos Cave Shop (Lake Hylia): The cave NW Lake Hylia diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 0d3f502b..2899b28b 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -3364,7 +3364,7 @@ door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0 '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 + 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x091b, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000)), '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)), @@ -3653,7 +3653,7 @@ ow_prize_table = {'Links House': (0x8b1, 0xb2d), 'Inverted Big Bomb Shop': (0x8b 'Light Hype Fairy': (0x940, 0xc80), 'Desert Fairy': (0x420, 0xe00), 'Kings Grave': (0x920, 0x520), - 'Tavern North': None, # can't mark this one technically + 'Tavern North': (0x270, 0x900), 'Chicken House': (0x120, 0x880), 'Aginahs Cave': (0x2e0, 0xd00), 'Sahasrahlas Hut': (0xcf0, 0x6c0), diff --git a/Main.py b/Main.py index 1c2357bb..19515022 100644 --- a/Main.py +++ b/Main.py @@ -118,6 +118,7 @@ def main(args, seed=None, fish=None): world.treasure_hunt_count = {k: int(v) for k, v in args.triforce_goal.items()} world.treasure_hunt_total = {k: int(v) for k, v in args.triforce_pool.items()} world.shufflelinks = args.shufflelinks.copy() + world.shuffletavern = args.shuffletavern.copy() world.pseudoboots = args.pseudoboots.copy() world.overworld_map = args.overworld_map.copy() world.restrict_boss_items = args.restrict_boss_items.copy() @@ -192,7 +193,7 @@ def main(args, seed=None, fish=None): logger.info(world.fish.translate("cli","cli","shuffling.world")) for player in range(1, world.players + 1): - if world.experimental[player] or (world.customizer and world.customizer.get_entrances()): + if world.experimental[player] or world.shuffle[player] in ['lite', 'lean'] or world.shuffletavern[player] or (world.customizer and world.customizer.get_entrances()): link_entrances_new(world, player) else: if world.mode[player] != 'inverted': diff --git a/README.md b/README.md index f419292f..f2980840 100644 --- a/README.md +++ b/README.md @@ -333,6 +333,11 @@ Start with dash ability, but no way to use boots to accomplish checks Whether to shuffle links house in most ER modes. +``` +--shuffletavern +``` + +Whether to shuffle the back of the tavern in most ER modes. ``` --bombbag diff --git a/Rom.py b/Rom.py index 616b7978..6289874a 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '01166fb16b38b49ef79acc9993dc4f02' +RANDOMIZERBASEHASH = 'e5556450b16f74709c666e419f2a42ad' class JsonRom(object): @@ -730,6 +730,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): else: # patch door table rom.write_byte(0xDBB73 + exit.addresses, exit.target) + if exit.name == 'Tavern North': + rom.write_byte(0x157D0, exit.target) if world.mode[player] == 'inverted': patch_shuffled_dark_sanc(world, rom, player) @@ -2048,6 +2050,8 @@ def write_strings(rom, world, player, team): entrances_to_hint.update({'Inverted Links House': 'The hero\'s old residence'}) else: entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) + if world.shuffletavern[player] and world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + entrances_to_hint.update({'Tavern North': 'A backdoor'}) if world.mode[player] == 'inverted': entrances_to_hint.update({'Inverted Dark Sanctuary': 'The dark sanctuary cave'}) entrances_to_hint.update({'Inverted Big Bomb Shop': 'The old hero\'s dark home'}) diff --git a/data/base2current.bps b/data/base2current.bps index bd6417a47ef665eabc70d7f6055e50cdcb4562a4..d44d2e2d89935611c1bbf1e5eee7fb9a50bb251f 100644 GIT binary patch delta 7654 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 K{mEBG82=AhtZ_&H delta 7235 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