From ced8e04aae0f675a7bcf35076372a03b114d5648 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Sun, 8 Dec 2019 12:41:28 +1100 Subject: [PATCH 1/5] Work around for json patch - split out bow limit into a separate patch so that it can be overridden properly. --- Rom.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Rom.py b/Rom.py index c18784aba..49e45974a 100644 --- a/Rom.py +++ b/Rom.py @@ -662,8 +662,10 @@ def patch_rom(world, player, rom): [difficulty.progressive_sword_limit, overflow_replacement, difficulty.progressive_shield_limit, overflow_replacement, difficulty.progressive_armor_limit, overflow_replacement, - difficulty.progressive_bottle_limit, overflow_replacement, - difficulty.progressive_bow_limit, overflow_replacement]) + difficulty.progressive_bottle_limit, overflow_replacement]) + + #Work around for json patch ordering issues - write bow limit separately so that it is replaced in the patch + rom.write_bytes(0x180098, [difficulty.progressive_bow_limit, overflow_replacement]) if difficulty.progressive_bow_limit < 2 and world.swords == 'swordless': rom.write_bytes(0x180098, [2, overflow_replacement]) From 9109d811fce3080702be23837405d4a467d9de59 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Thu, 2 Jan 2020 11:09:14 +1100 Subject: [PATCH 2/5] Add shop door ids to tables (used when shop locations are vanilla) Do not replace Upgrade Fairy with retro shop --- BaseClasses.py | 5 ++++- InvertedRegions.py | 28 ++++++++++++++-------------- ItemList.py | 6 +++--- Main.py | 2 +- Regions.py | 28 ++++++++++++++-------------- 5 files changed, 36 insertions(+), 33 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index c6d63713e..625477468 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -871,9 +871,10 @@ class ShopType(Enum): UpgradeShop = 2 class Shop(object): - def __init__(self, region, room_id, type, shopkeeper_config, replaceable): + def __init__(self, region, room_id, default_door_id, type, shopkeeper_config, replaceable): self.region = region self.room_id = room_id + self.default_door_id = default_door_id self.type = type self.inventory = [None, None, None] self.shopkeeper_config = shopkeeper_config @@ -893,6 +894,8 @@ def get_bytes(self): config = self.item_count if len(entrances) == 1 and entrances[0].addresses: door_id = entrances[0].addresses+1 + elif self.default_door_id is not None: + door_id = self.default_door_id else: door_id = 0 config |= 0x40 # ignore door id diff --git a/InvertedRegions.py b/InvertedRegions.py index 7623b398e..196028714 100644 --- a/InvertedRegions.py +++ b/InvertedRegions.py @@ -302,16 +302,16 @@ def create_inverted_regions(world, player): create_cave_region(player, 'The Sky', 'A Dark Sky', None, ['DDM Landing','NEDW Landing', 'WDW Landing', 'SDW Landing', 'EDW Landing', 'DD Landing', 'DLHL Landing']) ] - for region_name, (room_id, shopkeeper, replaceable) in shop_table.items(): + for region_name, (room_id, default_door_id, shopkeeper, replaceable) in shop_table.items(): region = world.get_region(region_name, player) - shop = Shop(region, room_id, ShopType.Shop, shopkeeper, replaceable) + shop = Shop(region, room_id, default_door_id, ShopType.Shop, shopkeeper, replaceable) region.shop = shop world.shops.append(shop) for index, (item, price) in enumerate(default_shop_contents[region_name]): shop.add_inventory(index, item, price) region = world.get_region('Capacity Upgrade', player) - shop = Shop(region, 0x0115, ShopType.UpgradeShop, 0x04, True) + shop = Shop(region, 0x0115, 0x5D, ShopType.UpgradeShop, 0x04, True) region.shop = shop world.shops.append(shop) shop.add_inventory(0, 'Bomb Upgrade (+5)', 100, 7) @@ -373,18 +373,18 @@ def mark_dark_world_regions(world): seen.add(exit.connected_region) queue.append(exit.connected_region) -# (room_id, shopkeeper, replaceable) +# (room_id, default_door_id, shopkeeper, replaceable) shop_table = { - 'Cave Shop (Dark Death Mountain)': (0x0112, 0xC1, True), - 'Red Shield Shop': (0x0110, 0xC1, True), - 'Dark Lake Hylia Shop': (0x010F, 0xC1, True), - 'Dark World Lumberjack Shop': (0x010F, 0xC1, True), - 'Village of Outcasts Shop': (0x010F, 0xC1, True), - 'Dark World Potion Shop': (0x010F, 0xC1, True), - 'Light World Death Mountain Shop': (0x00FF, 0xA0, True), - 'Kakariko Shop': (0x011F, 0xA0, True), - 'Cave Shop (Lake Hylia)': (0x0112, 0xA0, True), - 'Potion Shop': (0x0109, 0xFF, False), + 'Cave Shop (Dark Death Mountain)': (0x0112, 0x6E, 0xC1, True), + 'Red Shield Shop': (0x0110, 0x75, 0xC1, True), + 'Dark Lake Hylia Shop': (0x010F, 0x74, 0xC1, True), + 'Dark World Lumberjack Shop': (0x010F, 0x57, 0xC1, True), + 'Village of Outcasts Shop': (0x010F, 0x60, 0xC1, True), + 'Dark World Potion Shop': (0x010F, 0x6F, 0xC1, True), + 'Light World Death Mountain Shop': (0x00FF, None, 0xA0, True), + 'Kakariko Shop': (0x011F, 0x46, 0xA0, True), + 'Cave Shop (Lake Hylia)': (0x0112, 0x58, 0xA0, True), + 'Potion Shop': (0x0109, 0x4C, 0xFF, False), # Bomb Shop not currently modeled as a shop, due to special nature of items } # region, [item] diff --git a/ItemList.py b/ItemList.py index aeb7e106f..d7e78dbc3 100644 --- a/ItemList.py +++ b/ItemList.py @@ -246,7 +246,7 @@ def set_up_take_anys(world, player): entrance = world.get_region(reg, player).entrances[0] connect_entrance(world, entrance, old_man_take_any, player) entrance.target = 0x58 - old_man_take_any.shop = Shop(old_man_take_any, 0x0112, ShopType.TakeAny, 0xE2, True) + old_man_take_any.shop = Shop(old_man_take_any, 0x0112, None, ShopType.TakeAny, 0xE2, True) world.shops.append(old_man_take_any.shop) old_man_take_any.shop.active = True @@ -269,7 +269,7 @@ def set_up_take_anys(world, player): entrance = world.get_region(reg, player).entrances[0] connect_entrance(world, entrance, take_any, player) entrance.target = target - take_any.shop = Shop(take_any, room_id, ShopType.TakeAny, 0xE3, True) + take_any.shop = Shop(take_any, room_id, None, ShopType.TakeAny, 0xE3, True) world.shops.append(take_any.shop) take_any.shop.active = True take_any.shop.add_inventory(0, 'Blue Potion', 0, 0) @@ -337,7 +337,7 @@ def set_up_shops(world, player): # Randomized changes to Shops if world.retro: - for shop in random.sample([s for s in world.shops if s.replaceable and s.region.player == player], 5): + for shop in random.sample([s for s in world.shops if s.replaceable and s.type == ShopType.Shop and s.region.player == player], 5): shop.active = True shop.add_inventory(0, 'Single Arrow', 80) shop.add_inventory(1, 'Small Key (Universal)', 100) diff --git a/Main.py b/Main.py index 9442c8abc..39087ae57 100644 --- a/Main.py +++ b/Main.py @@ -270,7 +270,7 @@ def copy_dynamic_regions_and_locations(world, ret): # Note: ideally exits should be copied here, but the current use case (Take anys) do not require this if region.shop: - new_reg.shop = Shop(new_reg, region.shop.room_id, region.shop.type, region.shop.shopkeeper_config, region.shop.replaceable) + new_reg.shop = Shop(new_reg, region.shop.room_id, region.shop.default_door_id, region.shop.type, region.shop.shopkeeper_config, region.shop.replaceable) ret.shops.append(new_reg.shop) for location in world.dynamic_locations: diff --git a/Regions.py b/Regions.py index 70ae3b0b8..3e14b395a 100644 --- a/Regions.py +++ b/Regions.py @@ -293,16 +293,16 @@ def create_regions(world, player): create_dw_region(player, 'Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop']) ] - for region_name, (room_id, shopkeeper, replaceable) in shop_table.items(): + for region_name, (room_id, default_door_id, shopkeeper, replaceable) in shop_table.items(): region = world.get_region(region_name, player) - shop = Shop(region, room_id, ShopType.Shop, shopkeeper, replaceable) + shop = Shop(region, room_id, default_door_id, ShopType.Shop, shopkeeper, replaceable) region.shop = shop world.shops.append(shop) for index, (item, price) in enumerate(default_shop_contents[region_name]): shop.add_inventory(index, item, price) region = world.get_region('Capacity Upgrade', player) - shop = Shop(region, 0x0115, ShopType.UpgradeShop, 0x04, True) + shop = Shop(region, 0x0115, 0x5D, ShopType.UpgradeShop, 0x04, True) region.shop = shop world.shops.append(shop) shop.add_inventory(0, 'Bomb Upgrade (+5)', 100, 7) @@ -364,18 +364,18 @@ def mark_light_world_regions(world): seen.add(exit.connected_region) queue.append(exit.connected_region) -# (room_id, shopkeeper, replaceable) +# (room_id, default_door_id, shopkeeper, replaceable) shop_table = { - 'Cave Shop (Dark Death Mountain)': (0x0112, 0xC1, True), - 'Red Shield Shop': (0x0110, 0xC1, True), - 'Dark Lake Hylia Shop': (0x010F, 0xC1, True), - 'Dark World Lumberjack Shop': (0x010F, 0xC1, True), - 'Village of Outcasts Shop': (0x010F, 0xC1, True), - 'Dark World Potion Shop': (0x010F, 0xC1, True), - 'Light World Death Mountain Shop': (0x00FF, 0xA0, True), - 'Kakariko Shop': (0x011F, 0xA0, True), - 'Cave Shop (Lake Hylia)': (0x0112, 0xA0, True), - 'Potion Shop': (0x0109, 0xFF, False), + 'Cave Shop (Dark Death Mountain)': (0x0112, 0x6E, 0xC1, True), + 'Red Shield Shop': (0x0110, 0x75, 0xC1, True), + 'Dark Lake Hylia Shop': (0x010F, 0x74, 0xC1, True), + 'Dark World Lumberjack Shop': (0x010F, 0x57, 0xC1, True), + 'Village of Outcasts Shop': (0x010F, 0x60, 0xC1, True), + 'Dark World Potion Shop': (0x010F, 0x6F, 0xC1, True), + 'Light World Death Mountain Shop': (0x00FF, None, 0xA0, True), + 'Kakariko Shop': (0x011F, 0x46, 0xA0, True), + 'Cave Shop (Lake Hylia)': (0x0112, 0x58, 0xA0, True), + 'Potion Shop': (0x0109, 0x4C, 0xFF, False), # Bomb Shop not currently modeled as a shop, due to special nature of items } # region, [item] From 584880be2038718745f0bcb4292d4b9ce71bfa55 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Thu, 2 Jan 2020 12:38:26 +1100 Subject: [PATCH 3/5] Add Python 3.8 compatibility - replace deprecated function time.clock with time.perf_counter --- AdjusterMain.py | 4 ++-- Main.py | 4 ++-- Plando.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/AdjusterMain.py b/AdjusterMain.py index 634661428..4646127c3 100644 --- a/AdjusterMain.py +++ b/AdjusterMain.py @@ -7,7 +7,7 @@ def adjust(args): - start = time.clock() + start = time.perf_counter() logger = logging.getLogger('') logger.info('Patching ROM.') @@ -31,6 +31,6 @@ def adjust(args): rom.write_to_file(output_path('%s.sfc' % outfilebase)) logger.info('Done. Enjoy.') - logger.debug('Total Time: %s', time.clock() - start) + logger.debug('Total Time: %s', time.perf_counter() - start) return args diff --git a/Main.py b/Main.py index 39087ae57..2a621f18b 100644 --- a/Main.py +++ b/Main.py @@ -21,7 +21,7 @@ __version__ = '0.6.3-pre' def main(args, seed=None): - start = time.clock() + start = time.perf_counter() # initialize the world world = World(args.multi, args.shuffle, args.logic, args.mode, args.swords, args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm, not args.nodungeonitems, args.accessibility, args.shuffleganon, args.quickswap, args.fastmenu, args.disablemusic, args.keysanity, args.retro, args.custom, args.customitemarray, args.shufflebosses, args.hints) @@ -172,7 +172,7 @@ def main(args, seed=None): world.spoiler.to_file(output_path('%s_Spoiler.txt' % outfilebase)) logger.info('Done. Enjoy.') - logger.debug('Total Time: %s', time.clock() - start) + logger.debug('Total Time: %s', time.perf_counter() - start) return world diff --git a/Plando.py b/Plando.py index 290e212b5..1f2992bf8 100755 --- a/Plando.py +++ b/Plando.py @@ -20,7 +20,7 @@ __version__ = '0.2-dev' def main(args): - start_time = time.clock() + start_time = time.perf_counter() # initialize the world world = World(1, 'vanilla', 'noglitches', 'standard', 'normal', 'none', 'on', 'ganon', 'freshness', False, False, False, args.quickswap, args.fastmenu, args.disablemusic, False, False, False, None, 'none', False) @@ -89,7 +89,7 @@ def main(args): world.spoiler.to_file('%s_Spoiler.txt' % outfilebase) logger.info('Done. Enjoy.') - logger.debug('Total Time: %s', time.clock() - start_time) + logger.debug('Total Time: %s', time.perf_counter() - start_time) return world From 699b4c55a26dbf16980a99e429685e85dec09939 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Thu, 2 Jan 2020 16:23:03 +1100 Subject: [PATCH 4/5] Remove Capacity Upgrade from Take Any locations, to match item randomizer --- ItemList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ItemList.py b/ItemList.py index d7e78dbc3..223552190 100644 --- a/ItemList.py +++ b/ItemList.py @@ -228,7 +228,7 @@ def generate_itempool(world, player): 'Bonk Fairy (Dark)', 'Lake Hylia Healer Fairy', 'Swamp Healer Fairy', 'Desert Healer Fairy', 'Dark Lake Hylia Healer Fairy', 'Dark Lake Hylia Ledge Healer Fairy', 'Dark Desert Healer Fairy', 'Dark Death Mountain Healer Fairy', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', - 'Kakariko Gamble Game', 'Capacity Upgrade', '50 Rupee Cave', 'Lost Woods Gamble', 'Hookshot Fairy', + 'Kakariko Gamble Game', '50 Rupee Cave', 'Lost Woods Gamble', 'Hookshot Fairy', 'Palace of Darkness Hint', 'East Dark World Hint', 'Archery Game', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Dark Desert Hint'] From 74701b88a15b69f8253c6b8a49a89cbf5c375064 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Fri, 3 Jan 2020 08:27:22 +1100 Subject: [PATCH 5/5] Swap implementation of Take Any fix to match Multiworld. --- BaseClasses.py | 9 +++------ InvertedRegions.py | 28 ++++++++++++++-------------- ItemList.py | 4 ++-- Main.py | 2 +- Regions.py | 28 ++++++++++++++-------------- 5 files changed, 34 insertions(+), 37 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 625477468..a04877da1 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -871,10 +871,9 @@ class ShopType(Enum): UpgradeShop = 2 class Shop(object): - def __init__(self, region, room_id, default_door_id, type, shopkeeper_config, replaceable): + def __init__(self, region, room_id, type, shopkeeper_config, replaceable): self.region = region self.room_id = room_id - self.default_door_id = default_door_id self.type = type self.inventory = [None, None, None] self.shopkeeper_config = shopkeeper_config @@ -892,10 +891,8 @@ def get_bytes(self): # [id][roomID-low][roomID-high][doorID][zero][shop_config][shopkeeper_config][sram_index] entrances = self.region.entrances config = self.item_count - if len(entrances) == 1 and entrances[0].addresses: - door_id = entrances[0].addresses+1 - elif self.default_door_id is not None: - door_id = self.default_door_id + if len(entrances) == 1 and entrances[0].name in door_addresses: + door_id = door_addresses[entrances[0].name][0]+1 else: door_id = 0 config |= 0x40 # ignore door id diff --git a/InvertedRegions.py b/InvertedRegions.py index 196028714..7623b398e 100644 --- a/InvertedRegions.py +++ b/InvertedRegions.py @@ -302,16 +302,16 @@ def create_inverted_regions(world, player): create_cave_region(player, 'The Sky', 'A Dark Sky', None, ['DDM Landing','NEDW Landing', 'WDW Landing', 'SDW Landing', 'EDW Landing', 'DD Landing', 'DLHL Landing']) ] - for region_name, (room_id, default_door_id, shopkeeper, replaceable) in shop_table.items(): + for region_name, (room_id, shopkeeper, replaceable) in shop_table.items(): region = world.get_region(region_name, player) - shop = Shop(region, room_id, default_door_id, ShopType.Shop, shopkeeper, replaceable) + shop = Shop(region, room_id, ShopType.Shop, shopkeeper, replaceable) region.shop = shop world.shops.append(shop) for index, (item, price) in enumerate(default_shop_contents[region_name]): shop.add_inventory(index, item, price) region = world.get_region('Capacity Upgrade', player) - shop = Shop(region, 0x0115, 0x5D, ShopType.UpgradeShop, 0x04, True) + shop = Shop(region, 0x0115, ShopType.UpgradeShop, 0x04, True) region.shop = shop world.shops.append(shop) shop.add_inventory(0, 'Bomb Upgrade (+5)', 100, 7) @@ -373,18 +373,18 @@ def mark_dark_world_regions(world): seen.add(exit.connected_region) queue.append(exit.connected_region) -# (room_id, default_door_id, shopkeeper, replaceable) +# (room_id, shopkeeper, replaceable) shop_table = { - 'Cave Shop (Dark Death Mountain)': (0x0112, 0x6E, 0xC1, True), - 'Red Shield Shop': (0x0110, 0x75, 0xC1, True), - 'Dark Lake Hylia Shop': (0x010F, 0x74, 0xC1, True), - 'Dark World Lumberjack Shop': (0x010F, 0x57, 0xC1, True), - 'Village of Outcasts Shop': (0x010F, 0x60, 0xC1, True), - 'Dark World Potion Shop': (0x010F, 0x6F, 0xC1, True), - 'Light World Death Mountain Shop': (0x00FF, None, 0xA0, True), - 'Kakariko Shop': (0x011F, 0x46, 0xA0, True), - 'Cave Shop (Lake Hylia)': (0x0112, 0x58, 0xA0, True), - 'Potion Shop': (0x0109, 0x4C, 0xFF, False), + 'Cave Shop (Dark Death Mountain)': (0x0112, 0xC1, True), + 'Red Shield Shop': (0x0110, 0xC1, True), + 'Dark Lake Hylia Shop': (0x010F, 0xC1, True), + 'Dark World Lumberjack Shop': (0x010F, 0xC1, True), + 'Village of Outcasts Shop': (0x010F, 0xC1, True), + 'Dark World Potion Shop': (0x010F, 0xC1, True), + 'Light World Death Mountain Shop': (0x00FF, 0xA0, True), + 'Kakariko Shop': (0x011F, 0xA0, True), + 'Cave Shop (Lake Hylia)': (0x0112, 0xA0, True), + 'Potion Shop': (0x0109, 0xFF, False), # Bomb Shop not currently modeled as a shop, due to special nature of items } # region, [item] diff --git a/ItemList.py b/ItemList.py index 223552190..28edbdf66 100644 --- a/ItemList.py +++ b/ItemList.py @@ -246,7 +246,7 @@ def set_up_take_anys(world, player): entrance = world.get_region(reg, player).entrances[0] connect_entrance(world, entrance, old_man_take_any, player) entrance.target = 0x58 - old_man_take_any.shop = Shop(old_man_take_any, 0x0112, None, ShopType.TakeAny, 0xE2, True) + old_man_take_any.shop = Shop(old_man_take_any, 0x0112, ShopType.TakeAny, 0xE2, True) world.shops.append(old_man_take_any.shop) old_man_take_any.shop.active = True @@ -269,7 +269,7 @@ def set_up_take_anys(world, player): entrance = world.get_region(reg, player).entrances[0] connect_entrance(world, entrance, take_any, player) entrance.target = target - take_any.shop = Shop(take_any, room_id, None, ShopType.TakeAny, 0xE3, True) + take_any.shop = Shop(take_any, room_id, ShopType.TakeAny, 0xE3, True) world.shops.append(take_any.shop) take_any.shop.active = True take_any.shop.add_inventory(0, 'Blue Potion', 0, 0) diff --git a/Main.py b/Main.py index 2a621f18b..1e3860b64 100644 --- a/Main.py +++ b/Main.py @@ -270,7 +270,7 @@ def copy_dynamic_regions_and_locations(world, ret): # Note: ideally exits should be copied here, but the current use case (Take anys) do not require this if region.shop: - new_reg.shop = Shop(new_reg, region.shop.room_id, region.shop.default_door_id, region.shop.type, region.shop.shopkeeper_config, region.shop.replaceable) + new_reg.shop = Shop(new_reg, region.shop.room_id, region.shop.type, region.shop.shopkeeper_config, region.shop.replaceable) ret.shops.append(new_reg.shop) for location in world.dynamic_locations: diff --git a/Regions.py b/Regions.py index 3e14b395a..70ae3b0b8 100644 --- a/Regions.py +++ b/Regions.py @@ -293,16 +293,16 @@ def create_regions(world, player): create_dw_region(player, 'Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop']) ] - for region_name, (room_id, default_door_id, shopkeeper, replaceable) in shop_table.items(): + for region_name, (room_id, shopkeeper, replaceable) in shop_table.items(): region = world.get_region(region_name, player) - shop = Shop(region, room_id, default_door_id, ShopType.Shop, shopkeeper, replaceable) + shop = Shop(region, room_id, ShopType.Shop, shopkeeper, replaceable) region.shop = shop world.shops.append(shop) for index, (item, price) in enumerate(default_shop_contents[region_name]): shop.add_inventory(index, item, price) region = world.get_region('Capacity Upgrade', player) - shop = Shop(region, 0x0115, 0x5D, ShopType.UpgradeShop, 0x04, True) + shop = Shop(region, 0x0115, ShopType.UpgradeShop, 0x04, True) region.shop = shop world.shops.append(shop) shop.add_inventory(0, 'Bomb Upgrade (+5)', 100, 7) @@ -364,18 +364,18 @@ def mark_light_world_regions(world): seen.add(exit.connected_region) queue.append(exit.connected_region) -# (room_id, default_door_id, shopkeeper, replaceable) +# (room_id, shopkeeper, replaceable) shop_table = { - 'Cave Shop (Dark Death Mountain)': (0x0112, 0x6E, 0xC1, True), - 'Red Shield Shop': (0x0110, 0x75, 0xC1, True), - 'Dark Lake Hylia Shop': (0x010F, 0x74, 0xC1, True), - 'Dark World Lumberjack Shop': (0x010F, 0x57, 0xC1, True), - 'Village of Outcasts Shop': (0x010F, 0x60, 0xC1, True), - 'Dark World Potion Shop': (0x010F, 0x6F, 0xC1, True), - 'Light World Death Mountain Shop': (0x00FF, None, 0xA0, True), - 'Kakariko Shop': (0x011F, 0x46, 0xA0, True), - 'Cave Shop (Lake Hylia)': (0x0112, 0x58, 0xA0, True), - 'Potion Shop': (0x0109, 0x4C, 0xFF, False), + 'Cave Shop (Dark Death Mountain)': (0x0112, 0xC1, True), + 'Red Shield Shop': (0x0110, 0xC1, True), + 'Dark Lake Hylia Shop': (0x010F, 0xC1, True), + 'Dark World Lumberjack Shop': (0x010F, 0xC1, True), + 'Village of Outcasts Shop': (0x010F, 0xC1, True), + 'Dark World Potion Shop': (0x010F, 0xC1, True), + 'Light World Death Mountain Shop': (0x00FF, 0xA0, True), + 'Kakariko Shop': (0x011F, 0xA0, True), + 'Cave Shop (Lake Hylia)': (0x0112, 0xA0, True), + 'Potion Shop': (0x0109, 0xFF, False), # Bomb Shop not currently modeled as a shop, due to special nature of items } # region, [item]