From 6f0511c0476fba111a690e3e815c48fbae0a6a12 Mon Sep 17 00:00:00 2001 From: pepperpow Date: Wed, 23 Dec 2020 16:36:06 -0600 Subject: [PATCH] Move shop table adjustments outside of Rom.py --- Main.py | 57 ++++++++++++++++++++++++++++++++++++++------------------- Rom.py | 37 ------------------------------------- 2 files changed, 38 insertions(+), 56 deletions(-) diff --git a/Main.py b/Main.py index 4401d542..f3469792 100644 --- a/Main.py +++ b/Main.py @@ -179,34 +179,18 @@ def main(args, seed=None): if world.players > 1: balance_multiworld_progression(world) - # for shop_location in [item for sublist in [shop.region.locations for shop in world.shops] for item in sublist if item.name != 'Potion Shop']: # we can just index shops directly - # # if shop, get slot - # slot_num = int(shop_location.name[-1]) - 1 - # default_slot = shop_location.parent_region.shop.inventory[slot_num] - # my_item = shop_location.item - # # if item is a rupee or single bee, or identical, label it - # if (default_slot is not None and default_slot['item'] == my_item.name) or 'Rupee' in my_item.name or (my_item.name in ['Bee']): - # for c in candidates: - # if c.item.name in ['Bee Trap', 'Shovel', 'Bug Catching Net', 'Cane of Byrna', 'Triforce Piece'] or\ - # any([x in c.item.name for x in ['Key', 'Map', 'Compass', 'Clock', 'Heart', 'Sword', 'Shield', 'Bomb', 'Arrow', 'Mail']]): - # if c.item_rule(my_item): # if rule is good... - # print('Swapping {} with {}:: {} ||| {}'.format(c, shop_location, c.item, my_item)) - # c.item, my_item = my_item, c.item - # if not world.can_beat_game(): - # c.item, my_item = my_item, c.item - # else: break - candidates = [l for l in world.get_locations() if l.item.name in ['Bee Trap', 'Shovel', 'Bug Catching Net', 'Cane of Byrna', 'Triforce Piece'] or any([x in l.item.name for x in ['Key', 'Map', 'Compass', 'Clock', 'Heart', 'Sword', 'Shield', 'Bomb', 'Arrow', 'Mail']])] world.random.shuffle(candidates) shop_slots = [item for sublist in [shop.region.locations for shop in world.shops] for item in sublist if item.name != 'Potion Shop'] shop_slots_adjusted = [] + shop_items = [] - for location in shop_slots: # we can just index shops directly + for location in shop_slots: slot_num = int(location.name[-1]) - 1 shop_item = location.parent_region.shop.inventory[slot_num] item = location.item - # if item is a rupee or single bee, or identical, swap it it + # if item is a rupee or single bee, or identical, swap it out if (shop_item is not None and shop_item['item'] == item.name) or 'Rupee' in item.name or (item.name in ['Bee']): for c in candidates: # chosen item locations if 'Rupee' in c.item.name or c.item.name in 'Bee': continue @@ -219,6 +203,41 @@ def main(args, seed=None): else: shop_slots_adjusted.append(location) break + # update table to location data + item = location.item + if (shop_item is not None and shop_item['item'] == item.name) or 'Rupee' in item.name or (item.name in ['Bee']): + # this will filter items that match the item in the shop or Rupees, or single bees + # really not a way for the player to know a renewable item from a player pool item + # bombs can be sitting on top of arrows or a potion refill, but dunno if that's a big deal + # this should rarely happen with the above code in place, and could be an option in config if necessary + logging.debug('skipping item shop {}'.format(item.name)) + else: + if shop_item is None: + location.parent_region.shop.add_inventory(slot_num, 'None', 0) + shop_item = location.parent_region.shop.inventory[slot_num] + else: + shop_item['replacement'] = shop_item['item'] + shop_item['replacement_price'] = shop_item['price'] + shop_item['item'] = item.name + if any([x in shop_item['item'] for x in ['Single Bomb', 'Single Arrow']]): + shop_item['price'] = world.random.randrange(5,35) + elif any([x in shop_item['item'] for x in ['Arrows', 'Bombs', 'Clock']]): + shop_item['price'] = world.random.randrange(20,120) + elif any([x in shop_item['item'] for x in ['Universal Key', 'Compass', 'Map', 'Small Key', 'Piece of Heart']]): + shop_item['price'] = world.random.randrange(50,150) + else: + shop_item['price'] = world.random.randrange(50,300) + + shop_item['max'] = 1 + shop_item['player'] = item.player if item.player != location.player else 0 + shop_items.append(shop_item) + + my_prices = [my_item['price'] for my_item in shop_items] + price_scale = (80*max(8, len(my_prices)+2))/sum(my_prices) + for i in shop_items: + i['price'] *= price_scale + if i['price'] < 5: i['price'] = 5 + else: i['price'] = int((i['price']//5)*5) logging.debug('Adjusting {} of {} shop slots'.format(len(shop_slots_adjusted), len(shop_slots))) logging.debug('Adjusted {} into shops'.format([x.item.name for x in shop_slots_adjusted])) diff --git a/Rom.py b/Rom.py index 150060b3..09fd37a5 100644 --- a/Rom.py +++ b/Rom.py @@ -629,7 +629,6 @@ def patch_rom(world, rom, player, team, enemized): distinguished_prog_bow_loc.item.code = 0x65 # patch items - shop_items = [] for location in world.get_locations(): if location.player != player: @@ -641,35 +640,6 @@ def patch_rom(world, rom, player, team, enemized): continue if 'Shop Slot' in location.name and location.parent_region.shop is not None: - slot_num = int(location.name[-1]) - 1 - my_item = location.parent_region.shop.inventory[slot_num] - item = location.item - if (my_item is not None and my_item['item'] == item.name) or 'Rupee' in item.name or (item.name in ['Bee']): - # this will filter items that match the item in the shop or Rupees, or single bees - # really not a way for the player to know a renewable item from a player pool item - # bombs can be sitting on top of arrows or a potion refill, but dunno if that's a big deal - logging.debug('skipping item shop {}'.format(item.name)) - else: - if my_item is None: - location.parent_region.shop.add_inventory(slot_num, 'None', 0) - my_item = location.parent_region.shop.inventory[slot_num] - else: - my_item['replacement'] = my_item['item'] - my_item['replacement_price'] = my_item['price'] - my_item['item'] = item.name - if any([x in my_item['item'] for x in ['Single Bomb', 'Single Arrow']]): - my_item['price'] = world.random.randrange(5,35) - elif any([x in my_item['item'] for x in ['Arrows', 'Bombs', 'Clock']]): - my_item['price'] = world.random.randrange(20,120) - elif any([x in my_item['item'] for x in ['Universal Key', 'Compass', 'Map', 'Small Key', 'Piece of Heart']]): - my_item['price'] = world.random.randrange(50,150) - else: - my_item['price'] = world.random.randrange(50,300) - - - my_item['max'] = 1 - my_item['player'] = item.player if item.player != location.player else 0 - shop_items.append(my_item) continue if not location.crystal: @@ -710,13 +680,6 @@ def patch_rom(world, rom, player, team, enemized): for music_address in music_addresses: rom.write_byte(music_address, music) - my_prices = [my_item['price'] for my_item in shop_items] - price_scale = (80*max(8, len(my_prices)+2))/sum(my_prices) - for i in shop_items: - i['price'] *= price_scale - if i['price'] < 5: i['price'] = 5 - else: i['price'] = int((i['price']//5)*5) - if world.mapshuffle[player]: rom.write_byte(0x155C9, local_random.choice([0x11, 0x16])) # Randomize GT music too with map shuffle