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

Various fixes to misc. location hints #2348

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
40 changes: 33 additions & 7 deletions HintList.py
Original file line number Diff line number Diff line change
Expand Up @@ -1871,55 +1871,81 @@ def rainbow_bridge_hint_kind(world: World) -> str:
misc_location_hint_table: dict[str, dict[str, Any]] = {
'10_skulltulas': {
'id': 0x9004,
'hint_location': '10 Skulltulas Reward Hint',
'item_location': 'Kak 10 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4110 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
'20_skulltulas': {
'id': 0x9005,
'hint_location': '20 Skulltulas Reward Hint',
'item_location': 'Kak 20 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4120 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
'30_skulltulas': {
'id': 0x9006,
'hint_location': '30 Skulltulas Reward Hint',
'item_location': 'Kak 30 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4130 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
'40_skulltulas': {
'id': 0x9007,
'hint_location': '40 Skulltulas Reward Hint',
'item_location': 'Kak 40 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4140 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
'50_skulltulas': {
'id': 0x9008,
'hint_location': '50 Skulltulas Reward Hint',
'item_location': 'Kak 50 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4150 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
'frogs2': {
'id': 0x022E,
'hint_location': 'ZR Frogs Ocarina Minigame Hint',
'item_location': 'ZR Frogs Ocarina Game',
'location_text': "Some frogs holding \x05\x42{item}\x05\x40 are looking at you from underwater...",
'location_fallback': "Some frogs are looking at you from underwater...",
},
'big_poes': {
'id': 0x70F5,
'hint_location': 'Market 10 Big Poes Hint',
'item_location': 'Market 10 Big Poes',
'location_text': "\x08Hey, young man. What's happening \x01today? Do you want\x01\x05\x41{item}\x05\x40?\x04\x1AIf you earn \x05\x41{poe_points} points\x05\x40, you'll\x01be a happy man! Heh heh.\x04\x08Your card now has \x05\x45\x1E\x01 \x05\x40points.\x01Come back again!\x01Heh heh heh!\x02",
'location_fallback': "\x08Hey, young man. What's happening \x01today? If you have a \x05\x41Poe\x05\x40, I will \x01buy it.\x04\x1AIf you earn \x05\x41{poe_points} points\x05\x40, you'll\x01be a happy man! Heh heh.\x04\x08Your card now has \x05\x45\x1E\x01 \x05\x40points.\x01Come back again!\x01Heh heh heh!\x02",
},
}

unique_merchant_hint_table: dict[str, dict[str, Any]] = {
'bean_salesman': {
'id': 0x405E,
'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,
'item_location': 'Wasteland Bombchu Salesman',
'location_text': '\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',
'location_fallback': '\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',
},
'medigoron': {
'id': 0x304F,
'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,
'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': 0x006D,
'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',
},
}

# Separate table for goal names to avoid duplicates in the hint table.
# Link's Pocket will always be an empty goal, but it's included here to
# prevent key errors during the dungeon reward lookup.
Expand Down
48 changes: 40 additions & 8 deletions 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, unique_merchant_hint_table
from Item import Item, make_event_item
from ItemList import REWARD_COLORS
from Messages import Message, COLOR_MAP, update_message_by_id
Expand Down Expand Up @@ -1318,9 +1318,16 @@ 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 in world.misc_hint_location_items.keys():
for hint_type in world.misc_hint_location_items:
location = world.get_location(misc_location_hint_table[hint_type]['item_location'])
if hint_type in world.settings.misc_hints and can_reach_hint(worlds, world.get_location(misc_location_hint_table[hint_type]['hint_location']), location):
if hint_type in world.settings.misc_hints and can_reach_hint(worlds, world.get_location(misc_location_hint_table[hint_type]['item_location'] + ' Hint'), 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 in world.unique_merchant_items:
location = world.get_location(unique_merchant_hint_table[hint_type]['item_location'])
if 'unique_merchants' in world.settings.misc_hints and can_reach_hint(worlds, world.get_location(unique_merchant_hint_table[hint_type]['item_location'] + ' Hint'), location):
item_world = location.world
if item_world.id not in checked_locations:
checked_locations[item_world.id] = set()
Expand Down Expand Up @@ -1353,7 +1360,7 @@ def build_world_gossip_hints(spoiler: Spoiler, world: World, checked_locations:
checked_locations = set()
checked_always_locations = set()

stone_ids = list(gossipLocations.keys())
stone_ids = list(gossipLocations)

world.distribution.configure_gossip(spoiler, stone_ids)

Expand Down Expand Up @@ -1825,8 +1832,10 @@ def build_misc_location_hints(world: World, messages: list[Message]) -> None:
item = world.misc_hint_location_items[hint_type]
poe_points = world.settings.big_poe_count * 100
if hint_type in world.settings.misc_hints:
text = data['location_text'].format(item=get_hint(get_item_generic_name(item),
world.settings.clearer_hints).text, poe_points=poe_points)
text = data['location_text'].format(
item=get_hint(get_item_generic_name(item), world.settings.clearer_hints).text,
poe_points=poe_points,
)
else:
text = data['location_fallback'].format(poe_points=poe_points)
update_message_by_id(messages, data['id'], text)
Expand All @@ -1835,12 +1844,35 @@ def build_misc_location_hints(world: World, messages: list[Message]) -> None:
if hint_type in world.settings.misc_hints:
if hint_type in world.misc_hint_location_items:
item = world.misc_hint_location_items[hint_type]
text = data['location_text'].format(item=get_hint(get_item_generic_name(item),
world.settings.clearer_hints).text)
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'], str(GossipText(text, ['Green'], prefix='')), 0x23)


def build_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 unique_merchant_hint_table.items():
if unique_merchants[hint_type]:
if 'unique_merchants' in world.settings.misc_hints and 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,
)
else:
text = data['location_fallback']

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


def get_raw_text(string: str) -> str:
text = ''
for char in string:
Expand Down
11 changes: 8 additions & 3 deletions 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, unique_merchant_hint_table
from LocationList import location_table, location_is_viewable, LocationAddress, LocationDefault, LocationFilterTags

if TYPE_CHECKING:
Expand Down Expand Up @@ -140,11 +140,16 @@ def maybe_set_misc_hints(self) -> None:
if hint_type not in self.item.world.misc_hint_item_locations and self.item.name == item:
self.item.world.misc_hint_item_locations[hint_type] = self
logging.getLogger('').debug(f'{item} [{self.item.world.id}] set to [{self.name}]')
for hint_type in misc_location_hint_table:
the_location = self.world.misc_hint_locations[hint_type]
for hint_type, data in misc_location_hint_table.items():
the_location = data['item_location']
if hint_type not in self.world.misc_hint_location_items and self.name == the_location:
self.world.misc_hint_location_items[hint_type] = self.item
logging.getLogger('').debug(f'{the_location} [{self.world.id}] set to [{self.item.name}]')
for hint_type, data in unique_merchant_hint_table.items():
the_location = data['item_location']
if hint_type not in self.world.unique_merchant_items and self.name == the_location:
self.world.unique_merchant_items[hint_type] = self.item
logging.getLogger('').debug(f'{the_location} [{self.world.id}] set to [{self.item.name}]')

def __str__(self) -> str:
return self.name
Expand Down
19 changes: 12 additions & 7 deletions LocationList.py
Original file line number Diff line number Diff line change
Expand Up @@ -2599,14 +2599,19 @@ 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)),
("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)),
("40 Skulltulas Reward Hint", ("Hint", None, None, None, None, None)),
("50 Skulltulas Reward Hint", ("Hint", None, None, None, None, None)),
("ZR Frogs Ocarina Minigame Hint", ("Hint", None, None, None, None, None)),
("Market 10 Big Poes Hint", ("Hint", None, None, None, None, None)),
("Ganondorf Hint", ("Hint", None, None, None, None, None)),
("Kak 10 Gold Skulltula Reward Hint", ("Hint", None, None, None, None, None)),
("Kak 20 Gold Skulltula Reward Hint", ("Hint", None, None, None, None, None)),
("Kak 30 Gold Skulltula Reward Hint", ("Hint", None, None, None, None, None)),
("Kak 40 Gold Skulltula Reward Hint", ("Hint", None, None, None, None, None)),
("Kak 50 Gold Skulltula Reward Hint", ("Hint", None, None, None, None, None)),
("ZR Frogs Ocarina Game Hint", ("Hint", None, None, None, None, None)),
("Market 10 Big Poes Hint", ("Hint", None, None, None, None, None)),
("ZR Magic Bean Salesman Hint", ("Hint", None, None, None, None, None)),
("Wasteland Bombchu Salesman Hint", ("Hint", None, None, None, None, None)),
("GC Medigoron Hint", ("Hint", None, None, None, None, None)),
("Kak Granny Buy Blue Potion Hint", ("Hint", None, None, None, None, None)),
("Market Treasure Chest Game Salesman Hint", ("Hint", None, None, None, None, None)),
])

location_sort_order: dict[str, int] = {
Expand Down
7 changes: 6 additions & 1 deletion Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,12 @@ 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()
spoiler.build_password(settings.password_lock)
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, unique_merchant_hint_table
from TextBox import line_wrap
from Utils import find_last

Expand Down Expand Up @@ -1303,6 +1303,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 unique_merchant_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 @@ -1315,6 +1316,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 unique_merchant_hint_table.values()] +
[message_id for (message_id, message) in KEYSANITY_MESSAGES] +
shuffle_messages.shop_item_messages +
shuffle_messages.scrubs_message_ids +
Expand Down
Loading
Loading