Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to fix unique merchants not being proper "hint" types #2170

Open
wants to merge 2 commits into
base: Dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions HintList.py
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,44 @@ def tokens_required_by_settings(world: World) -> int:
},
}

misc_unique_merchants_hint_table: dict[str, dict[str, Any]] = {
'bean_salesman': {
'id': 0x405E,
'hint_location': 'Bean Salesman Hint',
'item_location': 'ZR Magic Bean Salesman',
'location_text': '\x1AChomp chomp chomp...We have...\x01\x05\x41{item}\x05\x40!\x04\x05\x41\x0860 Rupees\x05\x40 and it\'s yours!\x01Keyahahah!\x01\x1B\x05\x42Yes\x01No\x05\x40\x02',
'location_fallback': '\x1AChomp chomp chomp...\x01We have... \x05\x41a mysterious item\x05\x40! \x01Do you want it...huh? Huh?\x04\x05\x41\x0860 Rupees\x05\x40 and it\'s yours!\x01Keyahahah!\x01\x1B\x05\x42Yes\x01No\x05\x40\x02',
},
'carpet_salesman': {
'id': 0x6077,
'hint_location': 'Wasteland Bombchu Salesman Hint',
'item_location': 'Wasteland Bombchu Salesman',
'location_text': '\x06\x41Well Come!\x04I am selling stuff, strange and \x01rare, from all over the world to \x01everybody.\x01Today\'s special is...\x04A mysterious item! \x01Intriguing! \x01I won\'t tell you what it is until \x01I see the money....\x04How about \x05\x41200 Rupees\x05\x40?\x01\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02',
'location_fallback': '\x06\x41Well Come!\x04I am selling stuff, strange and \x01rare. Today\'s special is...\x01\x05\x41{item}\x05\x40!\x04How about \x05\x41200 Rupees\x05\x40?\x01\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02',
},
'medigoron': {
'id': 0x304F,
'hint_location': 'Medigoron Hint',
'item_location': 'GC Medigoron',
'location_text': 'For 200 Rupees, how about buying...\x04\x05\x41{item}\x05\x40?\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02',
'location_fallback': 'How about buying this cool item for \x01200 Rupees?\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02',
},
'granny': {
'id': 0x500C,
'hint_location': 'Potion Selling Granny Hint',
'item_location': 'Kak Granny Buy Blue Potion',
'location_text': 'How about \x05\x41100 Rupees\x05\x40 for...\x04\x05\x41{item}\x05\x40?\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02',
'location_fallback': 'Mysterious item! How about\x01\x05\x41100 Rupees\x05\x40?\x01\x1B\x05\x42Buy\x01Don\'t buy\x05\x40\x02',
},
'chest_game': {
'id': 0x6D,
'hint_location': 'Treasure Chest Game Salesman Hint',
'item_location': 'Market Treasure Chest Game Salesman',
'location_text': 'I seem to have misplaced my\x01keys, but I have a fun item to\x01sell instead.\x01How about \x05\x4110 Rupees\x05\x40 for...\x04\x05\x41{item}\x05\x40?\x01\x1B\x05\x42Buy\x01Don\'t Buy\x05\x40\x02',
'location_fallback': 'I seem to have misplaced my\x01keys, but I have a fun item to\x01sell instead.\x04How about \x05\x4110 Rupees\x05\x40?\x01\x01\x1B\x05\x42Buy\x01Don\'t Buy\x05\x40\x02',
}
}

misc_location_hint_table: dict[str, dict[str, Any]] = {
'10_skulltulas': {
'id': 0x9004,
Expand Down
28 changes: 27 additions & 1 deletion Hints.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from urllib.error import URLError, HTTPError

from HintList import Hint, get_hint, get_multi, get_hint_group, get_upgrade_hint_list, hint_exclusions, \
misc_item_hint_table, misc_location_hint_table
misc_item_hint_table, misc_location_hint_table, misc_unique_merchants_hint_table
from Item import Item, make_event_item
from Messages import Message, COLOR_MAP, update_message_by_id
from Region import Region
Expand Down Expand Up @@ -1251,6 +1251,12 @@ def build_gossip_hints(spoiler: Spoiler, worlds: list[World]) -> None:
if item_world.id not in checked_locations:
checked_locations[item_world.id] = set()
checked_locations[item_world.id].add(location.name)
for hint_type, location in world.misc_hint_unique_merchant_locations.items():
if 'unique_merchants' in world.settings.misc_hints and can_reach_hint(worlds, world.get_location(misc_unique_merchants_hint_table[hint_type]['hint_location']), location):
item_world = location.world
if item_world.id not in checked_locations:
checked_locations[item_world.id] = set()
checked_locations[item_world.id].add(location.name)
for hint_type, location in world.misc_hint_item_locations.items():
if hint_type in world.settings.misc_hints and can_reach_hint(worlds, world.get_location(misc_item_hint_table[hint_type]['hint_location']), location):
item_world = location.world
Expand Down Expand Up @@ -1759,6 +1765,26 @@ def build_misc_location_hints(world: World, messages: list[Message]) -> None:
update_message_by_id(messages, data['id'], str(GossipText(text, ['Green'], prefix='')), 0x23)


def build_misc_unique_merchants_hints(world: World, messages: list[Message]) -> None:
unique_merchants = {
'bean_salesman': world.settings.shuffle_beans,
'carpet_salesman': world.settings.shuffle_expensive_merchants,
'medigoron': world.settings.shuffle_expensive_merchants,
'granny': world.settings.shuffle_expensive_merchants,
'chest_game': world.settings.shuffle_tcgkeys != 'vanilla',
}

for hint_type, data in misc_unique_merchants_hint_table.items():
if unique_merchants[hint_type] and 'unique_merchants' in world.settings.misc_hints:
text = data['location_fallback']
if hint_type in world.misc_hint_unique_merchant_locations:
item = world.misc_hint_unique_merchant_locations[hint_type].item
text = data['location_text'].format(item=get_hint(get_item_generic_name(item),
world.settings.clearer_hints).text)

update_message_by_id(messages, data['id'], text)


def get_raw_text(string: str) -> str:
text = ''
for char in string:
Expand Down
7 changes: 6 additions & 1 deletion Location.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from enum import Enum
from typing import TYPE_CHECKING, Optional, Any, overload

from HintList import misc_item_hint_table, misc_location_hint_table
from HintList import misc_item_hint_table, misc_location_hint_table, misc_unique_merchants_hint_table
from LocationList import location_table, location_is_viewable, LocationAddress, LocationDefault, LocationFilterTags

if TYPE_CHECKING:
Expand Down Expand Up @@ -135,6 +135,11 @@ def maybe_set_misc_hints(self) -> None:
if self.item.name not in self.item.world.hinted_dungeon_reward_locations:
self.item.world.hinted_dungeon_reward_locations[self.item.name] = self
logging.getLogger('').debug(f'{self.item.name} [{self.item.world.id}] set to [{self.name}]')
for merchant_hint in misc_unique_merchants_hint_table:
the_location = self.world.misc_hint_unique_merchants[merchant_hint]
if merchant_hint not in self.world.misc_hint_unique_merchant_locations and self.name == the_location:
self.world.misc_hint_unique_merchant_locations[merchant_hint] = self
logging.getLogger('').debug(f'{the_location} [{self.world.id}] set to [{self.item.name}]')
for hint_type in misc_item_hint_table:
item = self.item.world.misc_hint_items[hint_type]
if hint_type not in self.item.world.misc_hint_item_locations and self.item.name == item:
Expand Down
5 changes: 5 additions & 0 deletions LocationList.py
Original file line number Diff line number Diff line change
Expand Up @@ -2470,6 +2470,11 @@ def shop_address(shop_id: int, shelf_id: int) -> int:
("ToT Child Altar Hint", ("Hint", None, None, None, None, None)),
("ToT Adult Altar Hint", ("Hint", None, None, None, None, None)),
("Dampe Diary Hint", ("Hint", None, None, None, None, None)),
("Bean Salesman Hint", ("Hint", None, None, None, None, None)),
("Wasteland Bombchu Salesman Hint", ("Hint", None, None, None, None, None)),
("Medigoron Hint", ("Hint", None, None, None, None, None)),
("Potion Selling Granny Hint", ("Hint", None, None, None, None, None)),
("Treasure Chest Game Salesman Hint", ("Hint", None, None, None, None, None)),
("10 Skulltulas Reward Hint", ("Hint", None, None, None, None, None)),
("20 Skulltulas Reward Hint", ("Hint", None, None, None, None, None)),
("30 Skulltulas Reward Hint", ("Hint", None, None, None, None, None)),
Expand Down
2 changes: 1 addition & 1 deletion Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def make_spoiler(settings: Settings, worlds: list[World]) -> Spoiler:
logger.info('Calculating hint data.')
update_goal_items(spoiler)
build_gossip_hints(spoiler, worlds)
elif any(world.dungeon_rewards_hinted for world in worlds) or any(hint_type in settings.misc_hints for hint_type in misc_item_hint_table) or any(hint_type in settings.misc_hints for hint_type in misc_location_hint_table):
elif any(world.dungeon_rewards_hinted for world in worlds) or any(hint_type in settings.misc_hints for hint_type in misc_item_hint_table) or any(hint_type in settings.misc_hints for hint_type in misc_location_hint_table) or 'unique_merchants' in settings.misc_hints:
spoiler.find_misc_hint_items()
spoiler.build_file_hash()
return spoiler
Expand Down
4 changes: 3 additions & 1 deletion Messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from collections.abc import Callable, Iterable
from typing import TYPE_CHECKING, Optional, Any

from HintList import misc_item_hint_table, misc_location_hint_table
from HintList import misc_item_hint_table, misc_location_hint_table, misc_unique_merchants_hint_table
from TextBox import line_wrap
from Utils import find_last

Expand Down Expand Up @@ -1298,6 +1298,7 @@ def shuffle_messages(messages: list[Message], except_hints: bool = True) -> list
GOSSIP_STONE_MESSAGES + TEMPLE_HINTS_MESSAGES +
[data['id'] for data in misc_item_hint_table.values()] +
[data['id'] for data in misc_location_hint_table.values()] +
[data['id'] for data in misc_unique_merchants_hint_table.values()] +
[message_id for (message_id, message) in KEYSANITY_MESSAGES] + shuffle_messages.shop_item_messages +
shuffle_messages.scrubs_message_ids +
[0x5036, 0x70F5] # Chicken count and poe count respectively
Expand All @@ -1314,6 +1315,7 @@ def is_exempt(m: Message) -> bool:
GOSSIP_STONE_MESSAGES + TEMPLE_HINTS_MESSAGES +
[data['id'] for data in misc_item_hint_table.values()] +
[data['id'] for data in misc_location_hint_table.values()] +
[data['id'] for data in misc_unique_merchants_hint_table.values()] +
[message_id for (message_id, message) in KEYSANITY_MESSAGES] +
shuffle_messages.shop_item_messages +
shuffle_messages.scrubs_message_ids +
Expand Down
56 changes: 5 additions & 51 deletions Patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
from Entrance import Entrance
from HintList import get_hint
from Hints import GossipText, HintArea, write_gossip_stone_hints, build_altar_hints, \
build_ganon_text, build_misc_item_hints, build_misc_location_hints, get_simple_hint_no_prefix, get_item_generic_name
build_ganon_text, build_misc_item_hints, build_misc_location_hints, get_simple_hint_no_prefix, \
get_item_generic_name, build_misc_unique_merchants_hints
from Item import Item
from ItemPool import song_list, trade_items, child_trade_items
from Location import Location, DisableType
Expand Down Expand Up @@ -1819,6 +1820,9 @@ def calculate_traded_flags(world):
# build misc. location hints
build_misc_location_hints(world, messages)

# build misc. unique merchants hints
build_misc_unique_merchants_hints(world, messages)

if 'mask_shop' in world.settings.misc_hints:
rom.write_int32(rom.sym('CFG_MASK_SHOP_HINT'), 1)

Expand Down Expand Up @@ -2145,16 +2149,6 @@ def update_scrub_text(message: bytearray, text_replacement: list[str], default_p
if world.settings.shuffle_beans:
rom.write_byte(rom.sym('SHUFFLE_BEANS'), 0x01)
# Update bean salesman messages to better fit the fact that he sells a randomized item
if 'unique_merchants' not in world.settings.misc_hints:
update_message_by_id(messages, 0x405E, "\x1AChomp chomp chomp...\x01We have... \x05\x41a mysterious item\x05\x40! \x01Do you want it...huh? Huh?\x04\x05\x41\x0860 Rupees\x05\x40 and it's yours!\x01Keyahahah!\x01\x1B\x05\x42Yes\x01No\x05\x40\x02")
else:
location = world.get_location("ZR Magic Bean Salesman")
item_text = get_hint(get_item_generic_name(location.item), True).text
wrapped_item_text = line_wrap(item_text, False, False, False)
if wrapped_item_text != item_text:
update_message_by_id(messages, 0x405E, "\x1AChomp chomp chomp...We have...\x01\x05\x41" + wrapped_item_text + "\x05\x40!\x04\x05\x41\x0860 Rupees\x05\x40 and it's yours!\x01Keyahahah!\x01\x1B\x05\x42Yes\x01No\x05\x40\x02")
else:
update_message_by_id(messages, 0x405E, "\x1AChomp chomp chomp...We have...\x01\x05\x41" + item_text + "\x05\x40! \x01Do you want it...huh? Huh?\x04\x05\x41\x0860 Rupees\x05\x40 and it's yours!\x01Keyahahah!\x01\x1B\x05\x42Yes\x01No\x05\x40\x02")
update_message_by_id(messages, 0x4069, "You don't have enough money.\x01I can't sell it to you.\x01Chomp chomp...\x02")
update_message_by_id(messages, 0x406C, "We hope you like it!\x01Chomp chomp chomp.\x02")
# Change first magic bean to cost 60 (is used as the price for the one time item when beans are shuffled)
Expand All @@ -2163,44 +2157,14 @@ def update_scrub_text(message: bytearray, text_replacement: list[str], default_p
if world.settings.shuffle_expensive_merchants:
rom.write_byte(rom.sym('SHUFFLE_CARPET_SALESMAN'), 0x01)
# Update carpet salesman messages to better fit the fact that he sells a randomized item
if 'unique_merchants' not in world.settings.misc_hints:
update_message_by_id(messages, 0x6077, "\x06\x41Well Come!\x04I am selling stuff, strange and \x01rare, from all over the world to \x01everybody.\x01Today's special is...\x04A mysterious item! \x01Intriguing! \x01I won't tell you what it is until \x01I see the money....\x04How about \x05\x41200 Rupees\x05\x40?\x01\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02")
else:
location = world.get_location("Wasteland Bombchu Salesman")
item_text = get_hint(get_item_generic_name(location.item), True).text
wrapped_item_text = line_wrap(item_text, False, False, False)
if wrapped_item_text != item_text:
update_message_by_id(messages, 0x6077, "\x06\x41Well Come!\x04I am selling stuff, strange and \x01rare. Today's special is...\x01\x05\x41"+ wrapped_item_text + "\x05\x40!\x04How about \x05\x41200 Rupees\x05\x40?\x01\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02")
else:
update_message_by_id(messages, 0x6077, "\x06\x41Well Come!\x04I am selling stuff, strange and \x01rare, from all over the world to \x01everybody. Today's special is...\x01\x05\x41"+ wrapped_item_text + "\x05\x40! \x01\x04How about \x05\x41200 Rupees\x05\x40?\x01\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02")
update_message_by_id(messages, 0x6078, "Thank you very much!\x04The mark that will lead you to\x01the Spirit Temple is the \x05\x41flag on\x01the left \x05\x40outside the shop.\x01Be seeing you!\x02")

rom.write_byte(rom.sym('SHUFFLE_MEDIGORON'), 0x01)
# Update medigoron messages to better fit the fact that he sells a randomized item
update_message_by_id(messages, 0x304C, "I have something cool right here.\x01How about it...\x07\x30\x4F\x02")
update_message_by_id(messages, 0x304D, "How do you like it?\x02")
if 'unique_merchants' not in world.settings.misc_hints:
update_message_by_id(messages, 0x304F, "How about buying this cool item for \x01200 Rupees?\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02")
else:
location = world.get_location("GC Medigoron")
item_text = get_hint(get_item_generic_name(location.item), True).text
wrapped_item_text = line_wrap(item_text, False, False, False)
if wrapped_item_text != item_text:
update_message_by_id(messages, 0x304F, "For 200 Rupees, how about buying...\x04\x05\x41" + wrapped_item_text + "\x05\x40?\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02")
else:
update_message_by_id(messages, 0x304F, "For 200 Rupees, how about buying \x01\x05\x41" + item_text + "\x05\x40?\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02")

rom.write_byte(rom.sym('SHUFFLE_GRANNYS_POTION_SHOP'), 0x01)
if 'unique_merchants' not in world.settings.misc_hints:
update_message_by_id(messages, 0x500C, "Mysterious item! How about\x01\x05\x41100 Rupees\x05\x40?\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02")
else:
location = world.get_location("Kak Granny Buy Blue Potion")
item_text = get_hint(get_item_generic_name(location.item), True).text
wrapped_item_text = line_wrap(item_text, False, False, False)
if wrapped_item_text != item_text:
update_message_by_id(messages, 0x500C, "How about \x05\x41100 Rupees\x05\x40 for...\x04\x05\x41"+ wrapped_item_text +"\x05\x40?\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02")
else:
update_message_by_id(messages, 0x500C, "How about \x05\x41100 Rupees\x05\x40 for\x01\x05\x41"+ item_text +"\x05\x40?\x01\x1B\x05\x42Buy\x01Don't buy\x05\x40\x02")

new_message = "All right. You don't have to play\x01if you don't want to.\x0B\x02"
update_message_by_id(messages, 0x908B, new_message, 0x00)
Expand All @@ -2210,16 +2174,6 @@ def update_scrub_text(message: bytearray, text_replacement: list[str], default_p
else:
rom.write_byte(rom.sym('SHUFFLE_CHEST_GAME'), 0x01)
# Update Chest Game Salesman to better fit the fact he sells a randomized item
if 'unique_merchants' not in world.settings.misc_hints:
update_message_by_id(messages, 0x6D, "I seem to have misplaced my\x01keys, but I have a fun item to\x01sell instead.\x04How about \x05\x4110 Rupees\x05\x40?\x01\x01\x1B\x05\x42Buy\x01Don't Buy\x05\x40\x02")
else:
location = world.get_location("Market Treasure Chest Game Salesman")
item_text = get_hint(get_item_generic_name(location.item), True).text
wrapped_item_text = line_wrap(item_text, False, False, False)
if wrapped_item_text != item_text:
update_message_by_id(messages, 0x6D, "I seem to have misplaced my\x01keys, but I have a fun item to\x01sell instead.\x01How about \x05\x4110 Rupees\x05\x40 for...\x04\x05\x41" + wrapped_item_text + "\x05\x40?\x01\x1B\x05\x42Buy\x01Don't Buy\x05\x40\x02")
else:
update_message_by_id(messages, 0x6D, "I seem to have misplaced my\x01keys, but I have a fun item to\x01sell instead.\x04How about \x05\x4110 Rupees\x05\x40 for\x01\x05\x41" + item_text + "\x05\x40?\x01\x1B\x05\x42Buy\x01Don't Buy\x05\x40\x02")
update_message_by_id(messages, 0x908B, "That's OK!\x01More fun for me.\x0B\x02", 0x00)
update_message_by_id(messages, 0x6E, "Wait, that room was off limits!\x02")
update_message_by_id(messages, 0x704C, "I hope you like it!\x02")
Expand Down
Loading
Loading