parent
4370447adc
commit
fe218fffa6
|
@ -131,6 +131,7 @@ class World(object):
|
||||||
set_player_attr('triforce_pieces_available', 30)
|
set_player_attr('triforce_pieces_available', 30)
|
||||||
set_player_attr('triforce_pieces_required', 20)
|
set_player_attr('triforce_pieces_required', 20)
|
||||||
set_player_attr('shop_shuffle', 'off')
|
set_player_attr('shop_shuffle', 'off')
|
||||||
|
set_player_attr('potion_shop_shuffle', 'none')
|
||||||
set_player_attr('shuffle_prizes', "g")
|
set_player_attr('shuffle_prizes', "g")
|
||||||
set_player_attr('sprite_pool', [])
|
set_player_attr('sprite_pool', [])
|
||||||
set_player_attr('dark_room_logic', "lamp")
|
set_player_attr('dark_room_logic', "lamp")
|
||||||
|
@ -1312,6 +1313,7 @@ class Spoiler(object):
|
||||||
'triforce_pieces_available': self.world.triforce_pieces_available,
|
'triforce_pieces_available': self.world.triforce_pieces_available,
|
||||||
'triforce_pieces_required': self.world.triforce_pieces_required,
|
'triforce_pieces_required': self.world.triforce_pieces_required,
|
||||||
'shop_shuffle': self.world.shop_shuffle,
|
'shop_shuffle': self.world.shop_shuffle,
|
||||||
|
'potion_shop_shuffle': self.world.potion_shop_shuffle,
|
||||||
'shuffle_prizes': self.world.shuffle_prizes,
|
'shuffle_prizes': self.world.shuffle_prizes,
|
||||||
'sprite_pool': self.world.sprite_pool,
|
'sprite_pool': self.world.sprite_pool,
|
||||||
'restrict_dungeon_item_on_boss': self.world.restrict_dungeon_item_on_boss
|
'restrict_dungeon_item_on_boss': self.world.restrict_dungeon_item_on_boss
|
||||||
|
|
|
@ -330,6 +330,10 @@ def parse_arguments(argv, no_defaults=False):
|
||||||
p: randomize the prices of the items in shop inventories
|
p: randomize the prices of the items in shop inventories
|
||||||
u: shuffle capacity upgrades into the item pool
|
u: shuffle capacity upgrades into the item pool
|
||||||
''')
|
''')
|
||||||
|
parser.add_argument('--potion_shop_shuffle', default=defval('none'), choices=['none', 'a'], help='''\
|
||||||
|
Determine if potion shop shuffle items should be affected by the rules of shop shuffle.
|
||||||
|
Value `none` will only allow prices to be shuffled, `a` will allow any items to be shuffled.
|
||||||
|
''')
|
||||||
parser.add_argument('--shuffle_prizes', default=defval('g'), choices=['', 'g', 'b', 'gb'])
|
parser.add_argument('--shuffle_prizes', default=defval('g'), choices=['', 'g', 'b', 'gb'])
|
||||||
parser.add_argument('--sprite_pool', help='''\
|
parser.add_argument('--sprite_pool', help='''\
|
||||||
Specifies a colon separated list of sprites used for random/randomonevent. If not specified, the full sprite pool is used.''')
|
Specifies a colon separated list of sprites used for random/randomonevent. If not specified, the full sprite pool is used.''')
|
||||||
|
@ -382,7 +386,7 @@ def parse_arguments(argv, no_defaults=False):
|
||||||
'shufflebosses', 'enemy_shuffle', 'enemy_health', 'enemy_damage', 'shufflepots',
|
'shufflebosses', 'enemy_shuffle', 'enemy_health', 'enemy_damage', 'shufflepots',
|
||||||
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor',
|
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor',
|
||||||
'heartbeep', "skip_progression_balancing", "triforce_pieces_available",
|
'heartbeep', "skip_progression_balancing", "triforce_pieces_available",
|
||||||
"triforce_pieces_required", "shop_shuffle",
|
"triforce_pieces_required", "shop_shuffle", "potion_shop_shuffle",
|
||||||
'remote_items', 'progressive', 'dungeon_counters', 'glitch_boots', 'killable_thieves',
|
'remote_items', 'progressive', 'dungeon_counters', 'glitch_boots', 'killable_thieves',
|
||||||
'tile_shuffle', 'bush_shuffle', 'shuffle_prizes', 'sprite_pool', 'dark_room_logic', 'restrict_dungeon_item_on_boss',
|
'tile_shuffle', 'bush_shuffle', 'shuffle_prizes', 'sprite_pool', 'dark_room_logic', 'restrict_dungeon_item_on_boss',
|
||||||
'hud_palettes', 'sword_palettes', 'shield_palettes', 'link_palettes']:
|
'hud_palettes', 'sword_palettes', 'shield_palettes', 'link_palettes']:
|
||||||
|
|
|
@ -368,11 +368,15 @@ def shuffle_shops(world, items, player: int):
|
||||||
shops = []
|
shops = []
|
||||||
upgrade_shops = []
|
upgrade_shops = []
|
||||||
total_inventory = []
|
total_inventory = []
|
||||||
|
potion_option = world.potion_shop_shuffle[player]
|
||||||
for shop in world.shops:
|
for shop in world.shops:
|
||||||
if shop.region.player == player:
|
if shop.region.player == player:
|
||||||
if shop.type == ShopType.UpgradeShop:
|
if shop.type == ShopType.UpgradeShop:
|
||||||
upgrade_shops.append(shop)
|
upgrade_shops.append(shop)
|
||||||
elif shop.type == ShopType.Shop and shop.region.name != 'Potion Shop':
|
elif shop.type == ShopType.Shop:
|
||||||
|
if shop.region.name == 'Potion Shop' and potion_option in [None, '', 'none']:
|
||||||
|
upgrade_shops.append(shop) # just put it with the upgrade shops/caves so we don't shuffle the items, just prices
|
||||||
|
else:
|
||||||
shops.append(shop)
|
shops.append(shop)
|
||||||
total_inventory.extend(shop.inventory)
|
total_inventory.extend(shop.inventory)
|
||||||
|
|
||||||
|
|
1
Main.py
1
Main.py
|
@ -83,6 +83,7 @@ def main(args, seed=None):
|
||||||
world.triforce_pieces_available = args.triforce_pieces_available.copy()
|
world.triforce_pieces_available = args.triforce_pieces_available.copy()
|
||||||
world.triforce_pieces_required = args.triforce_pieces_required.copy()
|
world.triforce_pieces_required = args.triforce_pieces_required.copy()
|
||||||
world.shop_shuffle = args.shop_shuffle.copy()
|
world.shop_shuffle = args.shop_shuffle.copy()
|
||||||
|
world.potion_shop_shuffle = args.potion_shop_shuffle.copy()
|
||||||
world.progression_balancing = {player: not balance for player, balance in args.skip_progression_balancing.items()}
|
world.progression_balancing = {player: not balance for player, balance in args.skip_progression_balancing.items()}
|
||||||
world.shuffle_prizes = args.shuffle_prizes.copy()
|
world.shuffle_prizes = args.shuffle_prizes.copy()
|
||||||
world.sprite_pool = args.sprite_pool.copy()
|
world.sprite_pool = args.sprite_pool.copy()
|
||||||
|
|
|
@ -366,6 +366,10 @@ def roll_settings(weights):
|
||||||
if not ret.shop_shuffle:
|
if not ret.shop_shuffle:
|
||||||
ret.shop_shuffle = ''
|
ret.shop_shuffle = ''
|
||||||
|
|
||||||
|
ret.potion_shop_shuffle = get_choice('potion_shop_shuffle', weights, '')
|
||||||
|
if not ret.potion_shop_shuffle:
|
||||||
|
ret.potion_shop_shuffle = ''
|
||||||
|
|
||||||
ret.mode = get_choice('world_state', weights, None) # legacy support
|
ret.mode = get_choice('world_state', weights, None) # legacy support
|
||||||
if ret.mode == 'retro':
|
if ret.mode == 'retro':
|
||||||
ret.mode = 'open'
|
ret.mode = 'open'
|
||||||
|
|
|
@ -368,7 +368,9 @@ def create_shops(world, player: int):
|
||||||
cls_mapping = {ShopType.UpgradeShop: UpgradeShop,
|
cls_mapping = {ShopType.UpgradeShop: UpgradeShop,
|
||||||
ShopType.Shop: Shop,
|
ShopType.Shop: Shop,
|
||||||
ShopType.TakeAny: TakeAny}
|
ShopType.TakeAny: TakeAny}
|
||||||
for region_name, (room_id, type, shopkeeper, custom, locked, inventory) in shop_table.items():
|
my_shop_table = dict(shop_table)
|
||||||
|
|
||||||
|
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':
|
if world.mode[player] == 'inverted' and region_name == 'Dark Lake Hylia Shop':
|
||||||
locked = True
|
locked = True
|
||||||
inventory = [('Blue Potion', 160), ('Blue Shield', 50), ('Bombs (10)', 50)]
|
inventory = [('Blue Potion', 160), ('Blue Shield', 50), ('Bombs (10)', 50)]
|
||||||
|
@ -393,7 +395,7 @@ shop_table = {
|
||||||
'Light World Death Mountain Shop': (0x00FF, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
'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),
|
'Kakariko Shop': (0x011F, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
||||||
'Cave Shop (Lake Hylia)': (0x0112, 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)])
|
'Capacity Upgrade': (0x0115, ShopType.UpgradeShop, 0x04, True, True, [('Bomb Upgrade (+5)', 100, 7), ('Arrow Upgrade (+5)', 100, 7)])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
Rom.py
14
Rom.py
|
@ -1,7 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = 'e3714804e3fae1c6ac6100b94d1aee62'
|
RANDOMIZERBASEHASH = '383b6f24e7c154de0f215e09f3cc937e'
|
||||||
|
|
||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
|
@ -123,6 +123,9 @@ class LocalRom(object):
|
||||||
Patch.create_patch_file(local_path('basepatch.sfc'))
|
Patch.create_patch_file(local_path('basepatch.sfc'))
|
||||||
return
|
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')):
|
if os.path.isfile(local_path('data', 'basepatch.bmbp')):
|
||||||
_, target, buffer = Patch.create_rom_bytes(local_path('data', 'basepatch.bmbp'))
|
_, target, buffer = Patch.create_rom_bytes(local_path('data', 'basepatch.bmbp'))
|
||||||
if self.verify(buffer):
|
if self.verify(buffer):
|
||||||
|
@ -130,6 +133,7 @@ class LocalRom(object):
|
||||||
with open(local_path('basepatch.sfc'), 'wb') as stream:
|
with open(local_path('basepatch.sfc'), 'wb') as stream:
|
||||||
stream.write(buffer)
|
stream.write(buffer)
|
||||||
return
|
return
|
||||||
|
raise RuntimeError('Base patch unverified. Unable to continue.')
|
||||||
|
|
||||||
raise RuntimeError('Could not find Base Patch. 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:
|
for item in shop.inventory:
|
||||||
if item is None:
|
if item is None:
|
||||||
break
|
break
|
||||||
item_data = [shop_id, ItemFactory(item['item'], player).code] + int16_as_bytes(item['price']) + [
|
item_data = [shop_id, ItemFactory(item['item'], player).code]\
|
||||||
item['max'],
|
+ int16_as_bytes(item['price']) +\
|
||||||
ItemFactory(item['replacement'], player).code if item['replacement'] else 0xFF] + int16_as_bytes(
|
[item['max'], ItemFactory(item['replacement'], player).code if item['replacement'] else 0xFF] +\
|
||||||
item['replacement_price'])
|
int16_as_bytes(item['replacement_price']) + [0]
|
||||||
items_data.extend(item_data)
|
items_data.extend(item_data)
|
||||||
|
|
||||||
rom.write_bytes(0x184800, shop_data)
|
rom.write_bytes(0x184800, shop_data)
|
||||||
|
|
|
@ -1095,7 +1095,7 @@
|
||||||
"i": {
|
"i": {
|
||||||
"keyString": "shop_shuffle.i",
|
"keyString": "shop_shuffle.i",
|
||||||
"friendlyName": "Inventory Shuffle",
|
"friendlyName": "Inventory Shuffle",
|
||||||
"description": "Randomizes the inventories of shops.",
|
"description": "Shuffles the inventories of shops between each other.",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
},
|
},
|
||||||
"p": {
|
"p": {
|
||||||
|
@ -1124,6 +1124,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"potion_shop_shuffle": {
|
||||||
|
"keyString": "potion_shop_shuffle",
|
||||||
|
"friendlyName": "Potion Shop Shuffle Rules",
|
||||||
|
"description": "Influence on potion shop by shop shuffle options",
|
||||||
|
"inputType": "range",
|
||||||
|
"subOptions": {
|
||||||
|
"none": {
|
||||||
|
"keyString": "potion_shop_shuffle.none",
|
||||||
|
"friendlyName": "Vanilla Shops",
|
||||||
|
"description": "Shop contents are left unchanged, only prices.",
|
||||||
|
"defaultValue": 50
|
||||||
|
},
|
||||||
|
"a": {
|
||||||
|
"keyString": "potion_shop_shuffle.a",
|
||||||
|
"friendlyName": "Any Items can be shuffled in and out of the shop",
|
||||||
|
"description": "",
|
||||||
|
"defaultValue": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"shuffle_prizes": {
|
"shuffle_prizes": {
|
||||||
"keyString": "shuffle_prizes",
|
"keyString": "shuffle_prizes",
|
||||||
"friendlyName": "Prize Shuffle",
|
"friendlyName": "Prize Shuffle",
|
||||||
|
|
|
@ -211,9 +211,13 @@ 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
|
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
|
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
|
4: 0 # 100% of the non-essential item pool is replaced with bee traps
|
||||||
|
### Item Shuffle (shop)
|
||||||
|
potion_shop_shuffle: # influence of potion shop by shop shuffle
|
||||||
|
none: 50 # only shuffle price
|
||||||
|
a: 0 # generate/shuffle in any items
|
||||||
shop_shuffle:
|
shop_shuffle:
|
||||||
none: 50
|
none: 50
|
||||||
i: 0 # Shuffle the inventories of the shops around
|
i: 0 # Shuffle default inventories of the shops around
|
||||||
p: 0 # Randomize the prices of the items in shop inventories
|
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)
|
u: 0 # Shuffle capacity upgrades into the item pool (and allow them to traverse the multiworld)
|
||||||
ip: 0 # Shuffle inventories and randomize prices
|
ip: 0 # Shuffle inventories and randomize prices
|
||||||
|
|
Loading…
Reference in New Issue