If any shop shuffle slots are defined, define ALL of them to avoid information leakage.
This commit is contained in:
parent
f02715f988
commit
6095cfc586
|
@ -1074,6 +1074,7 @@ class Boss():
|
|||
|
||||
class Location():
|
||||
shop_slot: bool = False
|
||||
shop_slot_disabled: bool = False
|
||||
event: bool = False
|
||||
locked: bool = False
|
||||
|
||||
|
|
4
Main.py
4
Main.py
|
@ -10,7 +10,7 @@ import zlib
|
|||
import concurrent.futures
|
||||
|
||||
from BaseClasses import World, CollectionState, Item, Region, Location
|
||||
from Shops import ShopSlotFill, create_shops, SHOP_ID_START
|
||||
from Shops import ShopSlotFill, create_shops, SHOP_ID_START, FillDisabledShopSlots
|
||||
from Items import ItemFactory, item_table, item_name_groups
|
||||
from Regions import create_regions, mark_light_world_regions, lookup_vanilla_location_to_entrance
|
||||
from InvertedRegions import create_inverted_regions, mark_dark_world_regions
|
||||
|
@ -389,6 +389,8 @@ def main(args, seed=None):
|
|||
for item in world.precollected_items:
|
||||
precollected_items[item.player - 1].append(item.code)
|
||||
|
||||
FillDisabledShopSlots(world)
|
||||
|
||||
def write_multidata(roms):
|
||||
for future in roms:
|
||||
rom_name = future.result()
|
||||
|
|
31
Shops.py
31
Shops.py
|
@ -125,6 +125,17 @@ shop_class_mapping = {ShopType.UpgradeShop: UpgradeShop,
|
|||
ShopType.TakeAny: TakeAny}
|
||||
|
||||
|
||||
def FillDisabledShopSlots(world):
|
||||
shop_slots: Set[Location] = {location for shop_locations in (shop.region.locations for shop in world.shops)
|
||||
for location in shop_locations if location.shop_slot and location.shop_slot_disabled}
|
||||
for location in shop_slots:
|
||||
location.shop_slot_disabled = True
|
||||
slot_num = int(location.name[-1]) - 1
|
||||
shop: Shop = location.parent_region.shop
|
||||
location.item = ItemFactory(shop.inventory[slot_num]['item'], location.player)
|
||||
location.item_rule = lambda item: item.name == location.item.name and item.player == location.player
|
||||
|
||||
|
||||
def ShopSlotFill(world):
|
||||
shop_slots: Set[Location] = {location for shop_locations in (shop.region.locations for shop in world.shops)
|
||||
for location in shop_locations if location.shop_slot}
|
||||
|
@ -132,15 +143,11 @@ def ShopSlotFill(world):
|
|||
for location in shop_slots:
|
||||
slot_num = int(location.name[-1]) - 1
|
||||
shop: Shop = location.parent_region.shop
|
||||
if not shop.can_push_inventory(slot_num):
|
||||
if not shop.can_push_inventory(slot_num) or location.shop_slot_disabled:
|
||||
removed.add(location)
|
||||
shop.region.locations.remove(location)
|
||||
|
||||
if removed:
|
||||
shop_slots -= removed
|
||||
# remove locations that may no longer exist from caches, by flushing them entirely
|
||||
world.clear_location_cache()
|
||||
world._location_cache = {}
|
||||
|
||||
if shop_slots:
|
||||
from Fill import swap_location_item
|
||||
|
@ -168,7 +175,7 @@ def ShopSlotFill(world):
|
|||
world.random.shuffle(sphere)
|
||||
|
||||
for i, sphere in enumerate(candidates_per_sphere):
|
||||
current_shop_slots = [location for location in sphere if location.shop_slot]
|
||||
current_shop_slots = [location for location in sphere if location.shop_slot and not location.shop_slot_disabled]
|
||||
if current_shop_slots:
|
||||
|
||||
for location in current_shop_slots:
|
||||
|
@ -183,7 +190,7 @@ def ShopSlotFill(world):
|
|||
else:
|
||||
# This *should* never happen. But let's fail safely just in case.
|
||||
logger.warning("Ran out of ShopShuffle Item candidate locations.")
|
||||
shop.region.locations.remove(location)
|
||||
location.shop_slot_disabled = True
|
||||
continue
|
||||
item_name = location.item.name
|
||||
if any(x in item_name for x in ['Single Bomb', 'Single Arrow']):
|
||||
|
@ -239,14 +246,18 @@ def create_shops(world, player: int):
|
|||
world.shops.append(shop)
|
||||
for index, item in enumerate(inventory):
|
||||
shop.add_inventory(index, *item)
|
||||
if not locked and single_purchase_slots.pop():
|
||||
additional_item = 'Rupees (50)' # world.random.choice(['Rupees (50)', 'Rupees (100)', 'Rupees (300)'])
|
||||
if not locked and num_slots:
|
||||
slot_name = "{} Slot {}".format(region.name, index + 1)
|
||||
loc = Location(player, slot_name, address=shop_table_by_location[slot_name],
|
||||
parent=region, hint_text="for sale")
|
||||
loc.shop_slot = True
|
||||
loc.locked = True
|
||||
loc.item = ItemFactory(additional_item, player)
|
||||
if single_purchase_slots.pop():
|
||||
additional_item = 'Rupees (50)' # world.random.choice(['Rupees (50)', 'Rupees (100)', 'Rupees (300)'])
|
||||
loc.item = ItemFactory(additional_item, player)
|
||||
else:
|
||||
loc.item = ItemFactory('Nothing', player)
|
||||
loc.shop_slot_disabled = True
|
||||
shop.region.locations.append(loc)
|
||||
world.dynamic_locations.append(loc)
|
||||
world.clear_location_cache()
|
||||
|
|
Loading…
Reference in New Issue