parent
4370447adc
commit
4f58459742
|
@ -1239,6 +1239,7 @@ class Spoiler(object):
|
|||
if item is None:
|
||||
continue
|
||||
shopdata['item_{}'.format(index)] = "{} — {}".format(item['item'], item['price']) if item['price'] else item['item']
|
||||
|
||||
if item['max'] == 0:
|
||||
continue
|
||||
shopdata['item_{}'.format(index)] += " x {}".format(item['max'])
|
||||
|
|
|
@ -326,7 +326,9 @@ def parse_arguments(argv, no_defaults=False):
|
|||
parser.add_argument('--beemizer', default=defval(0), type=lambda value: min(max(int(value), 0), 4))
|
||||
parser.add_argument('--shop_shuffle', default='', help='''\
|
||||
combine letters for options:
|
||||
i: shuffle the inventories of the shops around
|
||||
g: generate default inventories for light and dark world shops, and unique shops
|
||||
f: generate default inventories for each shop individually
|
||||
i: shuffle the default inventories of the shops around
|
||||
p: randomize the prices of the items in shop inventories
|
||||
u: shuffle capacity upgrades into the item pool
|
||||
''')
|
||||
|
|
1
Fill.py
1
Fill.py
|
@ -152,6 +152,7 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
|||
fill_locations.remove(spot_to_fill)
|
||||
|
||||
world.random.shuffle(fill_locations)
|
||||
|
||||
prioitempool, fill_locations = fast_fill(world, prioitempool, fill_locations)
|
||||
|
||||
restitempool, fill_locations = fast_fill(world, restitempool, fill_locations)
|
||||
|
|
|
@ -379,7 +379,8 @@ def shuffle_shops(world, items, player: int):
|
|||
if 'p' in option:
|
||||
def price_adjust(price: int) -> int:
|
||||
# it is important that a base price of 0 always returns 0 as new price!
|
||||
return int(price * (0.5 + world.random.random() * 1.5))
|
||||
adjust = 2 if price < 100 else 5
|
||||
return int((price / adjust) * (0.5 + world.random.random() * 1.5)) * adjust
|
||||
|
||||
def adjust_item(item):
|
||||
if item:
|
||||
|
@ -394,6 +395,7 @@ def shuffle_shops(world, items, player: int):
|
|||
|
||||
if 'i' in option:
|
||||
world.random.shuffle(total_inventory)
|
||||
|
||||
i = 0
|
||||
for shop in shops:
|
||||
slots = shop.slots
|
||||
|
@ -464,13 +466,14 @@ def create_dynamic_shop_locations(world, player):
|
|||
if item is None:
|
||||
continue
|
||||
if item['create_location']:
|
||||
loc = Location(player, "{} Item {}".format(shop.region.name, i+1), parent=shop.region)
|
||||
loc = Location(player, "{} Slot Item {}".format(shop.region.name, i+1), parent=shop.region)
|
||||
shop.region.locations.append(loc)
|
||||
world.dynamic_locations.append(loc)
|
||||
|
||||
world.clear_location_cache()
|
||||
|
||||
world.push_item(loc, ItemFactory(item['item'], player), False)
|
||||
world.push_item(loc, ItemFactory(item['item'], player), False)
|
||||
|
||||
loc.event = True
|
||||
loc.locked = True
|
||||
|
||||
|
|
33
Regions.py
33
Regions.py
|
@ -368,7 +368,27 @@ def create_shops(world, player: int):
|
|||
cls_mapping = {ShopType.UpgradeShop: UpgradeShop,
|
||||
ShopType.Shop: Shop,
|
||||
ShopType.TakeAny: TakeAny}
|
||||
for region_name, (room_id, type, shopkeeper, custom, locked, inventory) in shop_table.items():
|
||||
option = world.shop_shuffle[player]
|
||||
my_shop_table = dict(shop_table)
|
||||
if 'g' in option or 'f' in option:
|
||||
new_basic_shop = world.random.sample(shop_generation_types['default'], k=3)
|
||||
new_dark_shop = world.random.sample(shop_generation_types['default'], k=3)
|
||||
for name, shop in my_shop_table.items():
|
||||
typ, shop_id, keeper, custom, locked, items = shop
|
||||
new_items = world.random.sample(shop_generation_types['default'], k=3)
|
||||
if 'f' not in option:
|
||||
if items == _basic_shop_defaults:
|
||||
new_items = new_basic_shop
|
||||
elif items == _dark_world_shop_defaults:
|
||||
new_items = new_dark_shop
|
||||
if name == 'Capacity Upgrade':
|
||||
continue
|
||||
if name == 'Potion Shop':
|
||||
continue
|
||||
keeper = world.random.choice([0xA0, 0xC1, 0xFF])
|
||||
my_shop_table[name] = (typ, shop_id, keeper, custom, locked, new_items)
|
||||
|
||||
for region_name, (room_id, type, shopkeeper, custom, locked, inventory) in my_shop_table.items():
|
||||
if world.mode[player] == 'inverted' and region_name == 'Dark Lake Hylia Shop':
|
||||
locked = True
|
||||
inventory = [('Blue Potion', 160), ('Blue Shield', 50), ('Bombs (10)', 50)]
|
||||
|
@ -379,6 +399,7 @@ def create_shops(world, player: int):
|
|||
for index, item in enumerate(inventory):
|
||||
shop.add_inventory(index, *item)
|
||||
|
||||
|
||||
# (type, room_id, shopkeeper, custom, locked, [items])
|
||||
# item = (item, price, max=0, replacement=None, replacement_price=0)
|
||||
_basic_shop_defaults = [('Red Potion', 150), ('Small Heart', 10), ('Bombs (10)', 50)]
|
||||
|
@ -393,10 +414,18 @@ shop_table = {
|
|||
'Light World Death Mountain Shop': (0x00FF, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
||||
'Kakariko Shop': (0x011F, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
||||
'Cave Shop (Lake Hylia)': (0x0112, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
||||
'Potion Shop': (0x0109, ShopType.Shop, 0xFF, False, True, [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)]),
|
||||
'Potion Shop': (0x0109, ShopType.Shop, 0xA0, True, False, [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)]),
|
||||
'Capacity Upgrade': (0x0115, ShopType.UpgradeShop, 0x04, True, True, [('Bomb Upgrade (+5)', 100, 7), ('Arrow Upgrade (+5)', 100, 7)])
|
||||
}
|
||||
|
||||
shop_generation_types = {
|
||||
'default': _basic_shop_defaults + [('Bombs (3)', 20), ('Green Potion', 90), ('Blue Potion', 190), ('Bee', 10), ('Single Arrow', 5)] + [('Red Shield', 500), ('Blue Shield', 50)],
|
||||
'potion': [('Red Potion', 150), ('Green Potion', 90), ('Blue Potion', 190)],
|
||||
'discount_potion': [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)],
|
||||
'bottle': [('Bee', 10)],
|
||||
'time': [('Red Clock', 100), ('Blue Clock', 200), ('Green Clock', 300)],
|
||||
}
|
||||
|
||||
old_location_address_to_new_location_address = {
|
||||
0x2eb18: 0x18001b, # Bottle Merchant
|
||||
0x33d68: 0x18001a, # Purple Chest
|
||||
|
|
14
Rom.py
14
Rom.py
|
@ -1,7 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = 'e3714804e3fae1c6ac6100b94d1aee62'
|
||||
RANDOMIZERBASEHASH = '383b6f24e7c154de0f215e09f3cc937e'
|
||||
|
||||
import io
|
||||
import json
|
||||
|
@ -122,6 +122,9 @@ class LocalRom(object):
|
|||
if not os.path.exists(local_path('data', 'basepatch.bmbp')):
|
||||
Patch.create_patch_file(local_path('basepatch.sfc'))
|
||||
return
|
||||
|
||||
if not os.path.isfile(local_path('data', 'basepatch.bmbp')):
|
||||
raise RuntimeError('Base patch unverified. Unable to continue.')
|
||||
|
||||
if os.path.isfile(local_path('data', 'basepatch.bmbp')):
|
||||
_, target, buffer = Patch.create_rom_bytes(local_path('data', 'basepatch.bmbp'))
|
||||
|
@ -130,6 +133,7 @@ class LocalRom(object):
|
|||
with open(local_path('basepatch.sfc'), 'wb') as stream:
|
||||
stream.write(buffer)
|
||||
return
|
||||
raise RuntimeError('Base patch unverified. Unable to continue.')
|
||||
|
||||
raise RuntimeError('Could not find Base Patch. Unable to continue.')
|
||||
|
||||
|
@ -1513,10 +1517,10 @@ def write_custom_shops(rom, world, player):
|
|||
for item in shop.inventory:
|
||||
if item is None:
|
||||
break
|
||||
item_data = [shop_id, ItemFactory(item['item'], player).code] + int16_as_bytes(item['price']) + [
|
||||
item['max'],
|
||||
ItemFactory(item['replacement'], player).code if item['replacement'] else 0xFF] + int16_as_bytes(
|
||||
item['replacement_price'])
|
||||
item_data = [shop_id, ItemFactory(item['item'], player).code]\
|
||||
+ int16_as_bytes(item['price']) +\
|
||||
[item['max'], ItemFactory(item['replacement'], player).code if item['replacement'] else 0xFF] +\
|
||||
int16_as_bytes(item['replacement_price']) + [0]
|
||||
items_data.extend(item_data)
|
||||
|
||||
rom.write_bytes(0x184800, shop_data)
|
||||
|
|
2
Rules.py
2
Rules.py
|
@ -85,7 +85,7 @@ def set_rules(world, player):
|
|||
add_rule(world.get_entrance('Ganons Tower', player), lambda state: state.world.get_entrance('Ganons Tower Ascent', player).can_reach(state), 'or')
|
||||
|
||||
set_bunny_rules(world, player, world.mode[player] == 'inverted')
|
||||
|
||||
|
||||
|
||||
def mirrorless_path_to_castle_courtyard(world, player):
|
||||
# If Agahnim is defeated then the courtyard needs to be accessible without using the mirror for the mirror offset glitch.
|
||||
|
|
|
@ -1092,10 +1092,22 @@
|
|||
"description": "Shop contents are left unchanged.",
|
||||
"defaultValue": 50
|
||||
},
|
||||
"g": {
|
||||
"keyString": "shop_shuffle.g",
|
||||
"friendlyName": "Inventory Generate",
|
||||
"description": "Generates new default base inventories of overworld and underworld shops.",
|
||||
"defaultValue": 0
|
||||
},
|
||||
"f": {
|
||||
"keyString": "shop_shuffle.f",
|
||||
"friendlyName": "Full Inventory Generate",
|
||||
"description": "Generates new base inventories of each individual shop.",
|
||||
"defaultValue": 0
|
||||
},
|
||||
"i": {
|
||||
"keyString": "shop_shuffle.i",
|
||||
"friendlyName": "Inventory Shuffle",
|
||||
"description": "Randomizes the inventories of shops.",
|
||||
"description": "Shuffles the inventories of shops between each other.",
|
||||
"defaultValue": 0
|
||||
},
|
||||
"p": {
|
||||
|
|
Binary file not shown.
|
@ -211,12 +211,16 @@ beemizer: # Remove items from the global item pool and replace them with single
|
|||
2: 0 # 60% of the non-essential item pool is replaced with bee traps, of which 20% could be single bees
|
||||
3: 0 # 100% of the non-essential item pool is replaced with bee traps, of which 50% could be single bees
|
||||
4: 0 # 100% of the non-essential item pool is replaced with bee traps
|
||||
### Item Shuffle (shop)
|
||||
shop_shuffle:
|
||||
none: 50
|
||||
i: 0 # Shuffle the inventories of the shops around
|
||||
g: 0 # Generate new default inventories for overworld/underworld shops, and unique shops
|
||||
f: 0 # Generate new default inventories for every shop independently
|
||||
i: 0 # Shuffle default inventories of the shops around
|
||||
p: 0 # Randomize the prices of the items in shop inventories
|
||||
u: 0 # Shuffle capacity upgrades into the item pool (and allow them to traverse the multiworld)
|
||||
ip: 0 # Shuffle inventories and randomize prices
|
||||
fpu: 0 # Generate new inventories, randomize prices and shuffle capacity upgrades into item pool
|
||||
uip: 0 # Shuffle inventories, randomize prices and shuffle capacity upgrades into the item pool
|
||||
# You can add more combos
|
||||
shuffle_prizes: # aka drops
|
||||
|
|
Loading…
Reference in New Issue