Skip to content

Commit

Permalink
LttP: deterministic shop_shuffle
Browse files Browse the repository at this point in the history
  • Loading branch information
Berserker66 authored and Jouramie committed Feb 28, 2024
1 parent 4ae3c47 commit d8263cb
Showing 1 changed file with 18 additions and 17 deletions.
35 changes: 18 additions & 17 deletions worlds/alttp/Shops.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class TakeAny(Shop):
2: ""
}


class UpgradeShop(Shop):
type = ShopType.UpgradeShop
# Potions break due to VRAM flags set in UpgradeShop.
Expand All @@ -173,9 +174,9 @@ def FillDisabledShopSlots(world):
location.item_rule = lambda item: item.name == location.item.name and item.player == location.player


def ShopSlotFill(world):
def ShopSlotFill(multiworld):
shop_slots: Set[ALttPLocation] = {location for shop_locations in
(shop.region.locations for shop in world.shops if shop.type != ShopType.TakeAny)
(shop.region.locations for shop in multiworld.shops if shop.type != ShopType.TakeAny)
for location in shop_locations if location.shop_slot is not None}

removed = set()
Expand All @@ -199,8 +200,8 @@ def ShopSlotFill(world):
blacklist_word in item_name for blacklist_word in blacklist_words)}
blacklist_words.add("Bee")

locations_per_sphere = list(
sorted(sphere, key=lambda location: location.name) for sphere in world.get_spheres())
locations_per_sphere = [sorted(sphere, key=lambda location: (location.name, location.player))
for sphere in multiworld.get_spheres()]

# currently special care needs to be taken so that Shop.region.locations.item is identical to Shop.inventory
# Potentially create Locations as needed and make inventory the only source, to prevent divergence
Expand All @@ -226,7 +227,7 @@ def ShopSlotFill(world):
x = 0
cumu_weights.append(len(current_candidates) + x)

world.random.shuffle(current_candidates)
multiworld.random.shuffle(current_candidates)

del locations_per_sphere

Expand All @@ -235,13 +236,13 @@ def ShopSlotFill(world):
# getting all candidates and shuffling them feels cpu expensive, there may be a better method
candidates = [(location, i) for i, candidates in enumerate(candidates_per_sphere[i:], start=i)
for location in candidates]
world.random.shuffle(candidates)
multiworld.random.shuffle(candidates)
for location in current_shop_slots:
shop: Shop = location.parent_region.shop
for index, (c, swapping_sphere_id) in enumerate(candidates): # chosen item locations
if c.item_rule(location.item) and location.item_rule(c.item):
swap_location_item(c, location, check_locked=False)
logger.debug(f'Swapping {c} into {location}:: {location.item}')
logger.debug(f"Swapping {c} into {location}:: {location.item}")
# remove candidate
candidates_per_sphere[swapping_sphere_id].remove(c)
candidates.pop(index)
Expand All @@ -256,26 +257,26 @@ def ShopSlotFill(world):
item_name = location.item.name
if location.item.game != "A Link to the Past":
if location.item.advancement:
price = world.random.randrange(8, 56)
price = multiworld.random.randrange(8, 56)
elif location.item.useful:
price = world.random.randrange(4, 28)
price = multiworld.random.randrange(4, 28)
else:
price = world.random.randrange(2, 14)
price = multiworld.random.randrange(2, 14)
elif any(x in item_name for x in
['Compass', 'Map', 'Single Bomb', 'Single Arrow', 'Piece of Heart']):
price = world.random.randrange(1, 7)
price = multiworld.random.randrange(1, 7)
elif any(x in item_name for x in ['Arrow', 'Bomb', 'Clock']):
price = world.random.randrange(2, 14)
price = multiworld.random.randrange(2, 14)
elif any(x in item_name for x in ['Small Key', 'Heart']):
price = world.random.randrange(4, 28)
price = multiworld.random.randrange(4, 28)
else:
price = world.random.randrange(8, 56)
price = multiworld.random.randrange(8, 56)

shop.push_inventory(location.shop_slot, item_name,
min(int(price * world.shop_price_modifier[location.player] / 100) * 5, 9999), 1,
min(int(price * multiworld.shop_price_modifier[location.player] / 100) * 5, 9999), 1,
location.item.player if location.item.player != location.player else 0)
if 'P' in world.shop_shuffle[location.player]:
price_to_funny_price(world, shop.inventory[location.shop_slot], location.player)
if 'P' in multiworld.shop_shuffle[location.player]:
price_to_funny_price(multiworld, shop.inventory[location.shop_slot], location.player)


def create_shops(world, player: int):
Expand Down

0 comments on commit d8263cb

Please sign in to comment.