diff --git a/HintList.py b/HintList.py index 4ec8cd472..e4816d578 100644 --- a/HintList.py +++ b/HintList.py @@ -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, diff --git a/Hints.py b/Hints.py index 13ed93c11..75116eea2 100644 --- a/Hints.py +++ b/Hints.py @@ -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 @@ -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 @@ -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: diff --git a/Location.py b/Location.py index 3cabfdb32..ae3e8858b 100644 --- a/Location.py +++ b/Location.py @@ -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: @@ -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: diff --git a/LocationList.py b/LocationList.py index 6f987ea46..bcdfb0480 100644 --- a/LocationList.py +++ b/LocationList.py @@ -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)), diff --git a/Main.py b/Main.py index 715bccc57..d3409e192 100644 --- a/Main.py +++ b/Main.py @@ -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 diff --git a/Messages.py b/Messages.py index 01ffc8c22..886bd2c57 100644 --- a/Messages.py +++ b/Messages.py @@ -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 @@ -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 @@ -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 + diff --git a/Patches.py b/Patches.py index b26b8dfb6..efd0c53fc 100644 --- a/Patches.py +++ b/Patches.py @@ -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 @@ -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) @@ -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) @@ -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) @@ -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") diff --git a/World.py b/World.py index 4161fcfbd..0e537e630 100644 --- a/World.py +++ b/World.py @@ -11,7 +11,8 @@ from Dungeon import Dungeon from Entrance import Entrance from Goals import Goal, GoalCategory -from HintList import get_required_hints, misc_item_hint_table, misc_location_hint_table +from HintList import get_required_hints, misc_item_hint_table, misc_location_hint_table, \ + misc_unique_merchants_hint_table from Hints import HintArea, hint_dist_keys, hint_dist_files from Item import Item, ItemFactory, ItemInfo, make_event_item from Location import Location, LocationFactory @@ -41,6 +42,7 @@ def __init__(self, world_id: int, settings: Settings, resolve_randomized_setting self.scrub_prices: dict[int, int] = {} self.maximum_wallets: int = 0 self.hinted_dungeon_reward_locations: dict[str, Location] = {} + self.misc_hint_unique_merchant_locations: dict[str, Location] = {} self.misc_hint_item_locations: dict[str, Location] = {} self.misc_hint_location_items: dict[str, Item] = {} self.triforce_count: int = 0 @@ -251,6 +253,7 @@ def __missing__(self, dungeon_name: str) -> EmptyDungeonInfo: self.always_hints: list[str] = [hint.name for hint in get_required_hints(self)] self.dungeon_rewards_hinted: bool = 'altar' in settings.misc_hints or settings.enhance_map_compass + self.misc_hint_unique_merchants: dict[str, str] = {hint_type: self.hint_dist_user.get('misc_hint_unique_merchants', {}).get(hint_type, data['item_location']) for hint_type, data in misc_unique_merchants_hint_table.items()} self.misc_hint_items: dict[str, str] = {hint_type: self.hint_dist_user.get('misc_hint_items', {}).get(hint_type, data['default_item']) for hint_type, data in misc_item_hint_table.items()} self.misc_hint_locations: dict[str, str] = {hint_type: self.hint_dist_user.get('misc_hint_locations', {}).get(hint_type, data['item_location']) for hint_type, data in misc_location_hint_table.items()} diff --git a/data/World/Overworld.json b/data/World/Overworld.json index 88b594e96..171040fc7 100644 --- a/data/World/Overworld.json +++ b/data/World/Overworld.json @@ -1083,7 +1083,8 @@ "Wasteland Crate After Quicksand 3": "can_break_crate", "Wasteland GS": "can_use(Hookshot) or can_use(Boomerang)", "Fairy Pot": "has_bottle", - "Nut Pot": "True" + "Nut Pot": "True", + "Wasteland Bombchu Salesman Hint": "can_jumpslash" }, "exits": { "Wasteland Near Crate": "logic_lens_wasteland or can_use(Lens_of_Truth)", @@ -1574,7 +1575,8 @@ (Small_Key_Treasure_Chest_Game, 5) and (shuffle_tcgkeys != 'vanilla' or can_use(Lens_of_Truth))", "Market Treasure Chest Game Room 5 Top": " (Small_Key_Treasure_Chest_Game, 5) and (shuffle_tcgkeys != 'vanilla' or can_use(Lens_of_Truth))", - "Market Treasure Chest Game Reward": "(Small_Key_Treasure_Chest_Game, 6)" + "Market Treasure Chest Game Reward": "(Small_Key_Treasure_Chest_Game, 6)", + "Treasure Chest Game Salesman Hint": "True" }, "exits": { "Market": "True" @@ -1871,7 +1873,8 @@ ((selected_adult_trade_item == 'Odd Potion' or selected_adult_trade_item == 'Poachers Saw' or selected_adult_trade_item == 'Broken Sword' or selected_adult_trade_item == 'Prescription' or selected_adult_trade_item == 'Eyeball Frog' or selected_adult_trade_item == 'Eyedrops' or - selected_adult_trade_item == 'Claim Check') and not adult_trade_shuffle))" + selected_adult_trade_item == 'Claim Check') and not adult_trade_shuffle))", + "Potion Selling Granny Hint": "'Odd Potion Access'" }, "exits": { "Kak Backyard": "True" @@ -2128,7 +2131,8 @@ can_summon_gossip_fairy_without_suns and has_bottle and (can_blast_or_smash or Progressive_Strength_Upgrade)", "Bug Rock": "(can_blast_or_smash or can_use(Silver_Gauntlets)) and has_bottle", - "Stick Pot": "is_child" + "Stick Pot": "is_child", + "Medigoron Hint": "is_adult and (can_blast_or_smash or Progressive_Strength_Upgrade)" }, "exits": { "Death Mountain": "True", @@ -2473,7 +2477,8 @@ "Bug Shrub": " (is_child or here(can_plant_bean) or Hover_Boots or logic_zora_river_lower) and can_cut_shrubs and has_bottle", - "ZR Frogs Ocarina Minigame Hint": "True" + "ZR Frogs Ocarina Minigame Hint": "True", + "Bean Salesman Hint": "is_child" }, "exits": { "ZR Front": "True",