Shop location sram offsets now fully static.
This commit is contained in:
parent
50888eaa6b
commit
a2eb666ae9
|
@ -2,7 +2,7 @@ from collections import namedtuple
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from BaseClasses import Region, RegionType, Location
|
from BaseClasses import Region, RegionType, Location
|
||||||
from Shops import ShopType, Shop, TakeAny
|
from Shops import ShopType, Shop, TakeAny, total_shop_slots
|
||||||
from Bosses import place_bosses
|
from Bosses import place_bosses
|
||||||
from Dungeons import get_dungeon_item_pool
|
from Dungeons import get_dungeon_item_pool
|
||||||
from EntranceShuffle import connect_entrance
|
from EntranceShuffle import connect_entrance
|
||||||
|
@ -563,7 +563,7 @@ def set_up_take_anys(world, player):
|
||||||
entrance = world.get_region(reg, player).entrances[0]
|
entrance = world.get_region(reg, player).entrances[0]
|
||||||
connect_entrance(world, entrance.name, old_man_take_any.name, player)
|
connect_entrance(world, entrance.name, old_man_take_any.name, player)
|
||||||
entrance.target = 0x58
|
entrance.target = 0x58
|
||||||
old_man_take_any.shop = TakeAny(old_man_take_any, 0x0112, 0xE2, True, True)
|
old_man_take_any.shop = TakeAny(old_man_take_any, 0x0112, 0xE2, True, True, total_shop_slots)
|
||||||
world.shops.append(old_man_take_any.shop)
|
world.shops.append(old_man_take_any.shop)
|
||||||
|
|
||||||
swords = [item for item in world.itempool if item.type == 'Sword' and item.player == player]
|
swords = [item for item in world.itempool if item.type == 'Sword' and item.player == player]
|
||||||
|
@ -585,7 +585,7 @@ def set_up_take_anys(world, player):
|
||||||
entrance = world.get_region(reg, player).entrances[0]
|
entrance = world.get_region(reg, player).entrances[0]
|
||||||
connect_entrance(world, entrance.name, take_any.name, player)
|
connect_entrance(world, entrance.name, take_any.name, player)
|
||||||
entrance.target = target
|
entrance.target = target
|
||||||
take_any.shop = TakeAny(take_any, room_id, 0xE3, True, True)
|
take_any.shop = TakeAny(take_any, room_id, 0xE3, True, True, total_shop_slots + num + 1)
|
||||||
world.shops.append(take_any.shop)
|
world.shops.append(take_any.shop)
|
||||||
take_any.shop.add_inventory(0, 'Blue Potion', 0, 0)
|
take_any.shop.add_inventory(0, 'Blue Potion', 0, 0)
|
||||||
take_any.shop.add_inventory(1, 'Boss Heart Container', 0, 0)
|
take_any.shop.add_inventory(1, 'Boss Heart Container', 0, 0)
|
||||||
|
|
2
Main.py
2
Main.py
|
@ -562,7 +562,7 @@ def copy_dynamic_regions_and_locations(world, ret):
|
||||||
|
|
||||||
if region.shop:
|
if region.shop:
|
||||||
new_reg.shop = region.shop.__class__(new_reg, region.shop.room_id, region.shop.shopkeeper_config,
|
new_reg.shop = region.shop.__class__(new_reg, region.shop.room_id, region.shop.shopkeeper_config,
|
||||||
region.shop.custom, region.shop.locked)
|
region.shop.custom, region.shop.locked, region.shop.sram_offset)
|
||||||
ret.shops.append(new_reg.shop)
|
ret.shops.append(new_reg.shop)
|
||||||
|
|
||||||
for location in world.dynamic_locations:
|
for location in world.dynamic_locations:
|
||||||
|
|
9
Rom.py
9
Rom.py
|
@ -1552,22 +1552,17 @@ def patch_race_rom(rom, world, player):
|
||||||
|
|
||||||
def write_custom_shops(rom, world, player):
|
def write_custom_shops(rom, world, player):
|
||||||
shops = sorted([shop for shop in world.shops if shop.custom and shop.region.player == player],
|
shops = sorted([shop for shop in world.shops if shop.custom and shop.region.player == player],
|
||||||
key=lambda shop: shop.region.name)
|
key=lambda shop: shop.sram_offset)
|
||||||
|
|
||||||
shop_data = bytearray()
|
shop_data = bytearray()
|
||||||
items_data = bytearray()
|
items_data = bytearray()
|
||||||
sram_offset = 0
|
|
||||||
|
|
||||||
for shop_id, shop in enumerate(shops):
|
for shop_id, shop in enumerate(shops):
|
||||||
if shop_id == len(shops) - 1:
|
if shop_id == len(shops) - 1:
|
||||||
shop_id = 0xFF
|
shop_id = 0xFF
|
||||||
bytes = shop.get_bytes()
|
bytes = shop.get_bytes()
|
||||||
bytes[0] = shop_id
|
bytes[0] = shop_id
|
||||||
bytes[-1] = sram_offset
|
bytes[-1] = shop.sram_offset
|
||||||
if shop.type == ShopType.TakeAny:
|
|
||||||
sram_offset += 1
|
|
||||||
else:
|
|
||||||
sram_offset += 3
|
|
||||||
shop_data.extend(bytes)
|
shop_data.extend(bytes)
|
||||||
# [id][item][price-low][price-high][max][repl_id][repl_price-low][repl_price-high][player]
|
# [id][item][price-low][price-high][max][repl_id][repl_price-low][repl_price-high][player]
|
||||||
for item in shop.inventory:
|
for item in shop.inventory:
|
||||||
|
|
39
Shops.py
39
Shops.py
|
@ -23,13 +23,14 @@ class Shop():
|
||||||
blacklist: Set[str] = set() # items that don't work, todo: actually check against this
|
blacklist: Set[str] = set() # items that don't work, todo: actually check against this
|
||||||
type = ShopType.Shop
|
type = ShopType.Shop
|
||||||
|
|
||||||
def __init__(self, region, room_id: int, shopkeeper_config: int, custom: bool, locked: bool):
|
def __init__(self, region, room_id: int, shopkeeper_config: int, custom: bool, locked: bool, sram_offset: int):
|
||||||
self.region = region
|
self.region = region
|
||||||
self.room_id = room_id
|
self.room_id = room_id
|
||||||
self.inventory: List[Optional[dict]] = [None] * self.slots
|
self.inventory: List[Optional[dict]] = [None] * self.slots
|
||||||
self.shopkeeper_config = shopkeeper_config
|
self.shopkeeper_config = shopkeeper_config
|
||||||
self.custom = custom
|
self.custom = custom
|
||||||
self.locked = locked
|
self.locked = locked
|
||||||
|
self.sram_offset = sram_offset
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def item_count(self) -> int:
|
def item_count(self) -> int:
|
||||||
|
@ -226,7 +227,7 @@ def create_shops(world, player: int):
|
||||||
new_basic_shop = world.random.sample(default_shop_table, k=3)
|
new_basic_shop = world.random.sample(default_shop_table, k=3)
|
||||||
new_dark_shop = world.random.sample(default_shop_table, k=3)
|
new_dark_shop = world.random.sample(default_shop_table, k=3)
|
||||||
for name, shop in player_shop_table.items():
|
for name, shop in player_shop_table.items():
|
||||||
typ, shop_id, keeper, custom, locked, items = shop
|
typ, shop_id, keeper, custom, locked, items, sram_offset = shop
|
||||||
if not locked:
|
if not locked:
|
||||||
new_items = world.random.sample(default_shop_table, k=3)
|
new_items = world.random.sample(default_shop_table, k=3)
|
||||||
if 'f' not in option:
|
if 'f' not in option:
|
||||||
|
@ -235,13 +236,13 @@ def create_shops(world, player: int):
|
||||||
elif items == _dark_world_shop_defaults:
|
elif items == _dark_world_shop_defaults:
|
||||||
new_items = new_dark_shop
|
new_items = new_dark_shop
|
||||||
keeper = world.random.choice([0xA0, 0xC1, 0xFF])
|
keeper = world.random.choice([0xA0, 0xC1, 0xFF])
|
||||||
player_shop_table[name] = ShopData(typ, shop_id, keeper, custom, locked, new_items)
|
player_shop_table[name] = ShopData(typ, shop_id, keeper, custom, locked, new_items, sram_offset)
|
||||||
if world.mode[player] == "inverted":
|
if world.mode[player] == "inverted":
|
||||||
player_shop_table["Dark Lake Hylia Shop"] = \
|
player_shop_table["Dark Lake Hylia Shop"] = \
|
||||||
player_shop_table["Dark Lake Hylia Shop"]._replace(locked=True, items=_inverted_hylia_shop_defaults)
|
player_shop_table["Dark Lake Hylia Shop"]._replace(locked=True, items=_inverted_hylia_shop_defaults)
|
||||||
for region_name, (room_id, type, shopkeeper, custom, locked, inventory) in player_shop_table.items():
|
for region_name, (room_id, type, shopkeeper, custom, locked, inventory, sram_offset) in player_shop_table.items():
|
||||||
region = world.get_region(region_name, player)
|
region = world.get_region(region_name, player)
|
||||||
shop: Shop = shop_class_mapping[type](region, room_id, shopkeeper, custom, locked)
|
shop: Shop = shop_class_mapping[type](region, room_id, shopkeeper, custom, locked, sram_offset)
|
||||||
region.shop = shop
|
region.shop = shop
|
||||||
world.shops.append(shop)
|
world.shops.append(shop)
|
||||||
for index, item in enumerate(inventory):
|
for index, item in enumerate(inventory):
|
||||||
|
@ -270,28 +271,29 @@ class ShopData(NamedTuple):
|
||||||
custom: bool
|
custom: bool
|
||||||
locked: bool
|
locked: bool
|
||||||
items: List
|
items: List
|
||||||
|
sram_offset: int
|
||||||
|
|
||||||
|
|
||||||
# (type, room_id, shopkeeper, custom, locked, [items])
|
# (type, room_id, shopkeeper, custom, locked, [items], sram_offset)
|
||||||
# item = (item, price, max=0, replacement=None, replacement_price=0)
|
# item = (item, price, max=0, replacement=None, replacement_price=0)
|
||||||
_basic_shop_defaults = [('Red Potion', 150), ('Small Heart', 10), ('Bombs (10)', 50)]
|
_basic_shop_defaults = [('Red Potion', 150), ('Small Heart', 10), ('Bombs (10)', 50)]
|
||||||
_dark_world_shop_defaults = [('Red Potion', 150), ('Blue Shield', 50), ('Bombs (10)', 50)]
|
_dark_world_shop_defaults = [('Red Potion', 150), ('Blue Shield', 50), ('Bombs (10)', 50)]
|
||||||
_inverted_hylia_shop_defaults = [('Blue Potion', 160), ('Blue Shield', 50), ('Bombs (10)', 50)]
|
_inverted_hylia_shop_defaults = [('Blue Potion', 160), ('Blue Shield', 50), ('Bombs (10)', 50)]
|
||||||
shop_table: Dict[str, ShopData] = {
|
shop_table: Dict[str, ShopData] = {
|
||||||
'Cave Shop (Dark Death Mountain)': ShopData(0x0112, ShopType.Shop, 0xC1, True, False, _basic_shop_defaults),
|
'Cave Shop (Dark Death Mountain)': ShopData(0x0112, ShopType.Shop, 0xC1, True, False, _basic_shop_defaults, 0),
|
||||||
'Red Shield Shop': ShopData(0x0110, ShopType.Shop, 0xC1, True, False,
|
'Red Shield Shop': ShopData(0x0110, ShopType.Shop, 0xC1, True, False,
|
||||||
[('Red Shield', 500), ('Bee', 10), ('Arrows (10)', 30)]),
|
[('Red Shield', 500), ('Bee', 10), ('Arrows (10)', 30)], 3),
|
||||||
'Dark Lake Hylia Shop': ShopData(0x010F, ShopType.Shop, 0xC1, True, False, _dark_world_shop_defaults),
|
'Dark Lake Hylia Shop': ShopData(0x010F, ShopType.Shop, 0xC1, True, False, _dark_world_shop_defaults, 6),
|
||||||
'Dark World Lumberjack Shop': ShopData(0x010F, ShopType.Shop, 0xC1, True, False, _dark_world_shop_defaults),
|
'Dark World Lumberjack Shop': ShopData(0x010F, ShopType.Shop, 0xC1, True, False, _dark_world_shop_defaults, 9),
|
||||||
'Village of Outcasts Shop': ShopData(0x010F, ShopType.Shop, 0xC1, True, False, _dark_world_shop_defaults),
|
'Village of Outcasts Shop': ShopData(0x010F, ShopType.Shop, 0xC1, True, False, _dark_world_shop_defaults, 12),
|
||||||
'Dark World Potion Shop': ShopData(0x010F, ShopType.Shop, 0xC1, True, False, _dark_world_shop_defaults),
|
'Dark World Potion Shop': ShopData(0x010F, ShopType.Shop, 0xC1, True, False, _dark_world_shop_defaults, 15),
|
||||||
'Light World Death Mountain Shop': ShopData(0x00FF, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
'Light World Death Mountain Shop': ShopData(0x00FF, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults, 18),
|
||||||
'Kakariko Shop': ShopData(0x011F, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
'Kakariko Shop': ShopData(0x011F, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults, 21),
|
||||||
'Cave Shop (Lake Hylia)': ShopData(0x0112, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
'Cave Shop (Lake Hylia)': ShopData(0x0112, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults, 24),
|
||||||
'Potion Shop': ShopData(0x0109, ShopType.Shop, 0xA0, True, True,
|
'Potion Shop': ShopData(0x0109, ShopType.Shop, 0xA0, True, True,
|
||||||
[('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)]),
|
[('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)], 27),
|
||||||
'Capacity Upgrade': ShopData(0x0115, ShopType.UpgradeShop, 0x04, True, True,
|
'Capacity Upgrade': ShopData(0x0115, ShopType.UpgradeShop, 0x04, True, True,
|
||||||
[('Bomb Upgrade (+5)', 100, 7), ('Arrow Upgrade (+5)', 100, 7)])
|
[('Bomb Upgrade (+5)', 100, 7), ('Arrow Upgrade (+5)', 100, 7)], 30)
|
||||||
}
|
}
|
||||||
|
|
||||||
total_shop_slots = len(shop_table) * 3
|
total_shop_slots = len(shop_table) * 3
|
||||||
|
@ -299,7 +301,8 @@ total_dynamic_shop_slots = sum(3 for shopname, data in shop_table.items() if not
|
||||||
|
|
||||||
SHOP_ID_START = 0x400000
|
SHOP_ID_START = 0x400000
|
||||||
shop_table_by_location_id = {cnt: s for cnt, s in enumerate(
|
shop_table_by_location_id = {cnt: s for cnt, s in enumerate(
|
||||||
(f"{name} Slot {num}" for name in sorted(shop_table) for num in range(1, 4)), start=SHOP_ID_START)}
|
(f"{name} Slot {num}" for name in [key for key, value in sorted(shop_table.items(), key=lambda item: item[1].sram_offset)]
|
||||||
|
for num in range(1, 4)), start=SHOP_ID_START)}
|
||||||
shop_table_by_location_id[(SHOP_ID_START + total_shop_slots)] = "Old Man Sword Cave"
|
shop_table_by_location_id[(SHOP_ID_START + total_shop_slots)] = "Old Man Sword Cave"
|
||||||
shop_table_by_location_id[(SHOP_ID_START + total_shop_slots + 1)] = "Take-Any #1"
|
shop_table_by_location_id[(SHOP_ID_START + total_shop_slots + 1)] = "Take-Any #1"
|
||||||
shop_table_by_location_id[(SHOP_ID_START + total_shop_slots + 2)] = "Take-Any #2"
|
shop_table_by_location_id[(SHOP_ID_START + total_shop_slots + 2)] = "Take-Any #2"
|
||||||
|
|
Loading…
Reference in New Issue