From 367282c98047285c24af4d160c094926ffd23c41 Mon Sep 17 00:00:00 2001 From: RawZ06 Date: Thu, 17 Jul 2025 20:24:32 +0200 Subject: [PATCH 1/7] Altar in child now give information about SoT and OoT --- Hints.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Hints.py b/Hints.py index bc7ebf39e5..25aa2d2ee5 100644 --- a/Hints.py +++ b/Hints.py @@ -1667,6 +1667,8 @@ def build_altar_hints(world: World, messages: list[Message], include_rewards: bo child_text += get_hint('Spiritual Stone Text Start', world.settings.clearer_hints).text + '\x04' for (reward, color) in boss_rewards_spiritual_stones: child_text += build_boss_string(reward, color, world) + child_text += build_oot_sot_hints(world) + child_text += '\x04' child_text += get_hint('Child Altar Text End', world.settings.clearer_hints).text child_text += '\x0B' update_message_by_id(messages, 0x707A, get_raw_text(child_text), 0x20) @@ -1713,6 +1715,16 @@ def build_boss_string(reward: str, color: str, world: World) -> str: text = GossipText(f"\x08\x13{item_icon}One {location_text}...", [color], prefix='') return str(text) + '\x04' +def build_oot_sot_hints(world: World) -> str: + sot_location = world.get_location('Song from Ocarina of Time') + oot_location = world.get_location('HF Ocarina of Time Item') + + sot_item = "#" + get_hint(get_item_generic_name(sot_location.item), world.settings.clearer_hints).text + '# ' + oot_item = "#" + get_hint(get_item_generic_name(oot_location.item), world.settings.clearer_hints).text + '# ' + + string = f"It is also written that reuniting #The Spiritual Stones# leads to " + sot_item + " and " + oot_item + '' + + return str(GossipText(string, ['Yellow', 'Blue', 'Blue'], prefix='')) def build_bridge_reqs_string(world: World) -> str: if world.settings.bridge == 'open': From d2f0c9716082b256f4141d4804b06a61c333c8d5 Mon Sep 17 00:00:00 2001 From: RawZ06 Date: Thu, 17 Jul 2025 20:24:32 +0200 Subject: [PATCH 2/7] Add an option for the child altar to provide SoT and OoT information --- Hints.py | 1 + SettingsList.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Hints.py b/Hints.py index 25aa2d2ee5..c96904ee7b 100644 --- a/Hints.py +++ b/Hints.py @@ -1667,6 +1667,7 @@ def build_altar_hints(world: World, messages: list[Message], include_rewards: bo child_text += get_hint('Spiritual Stone Text Start', world.settings.clearer_hints).text + '\x04' for (reward, color) in boss_rewards_spiritual_stones: child_text += build_boss_string(reward, color, world) + if 'altar_child_oot' in world.settings.misc_hints: child_text += build_oot_sot_hints(world) child_text += '\x04' child_text += get_hint('Child Altar Text End', world.settings.clearer_hints).text diff --git a/SettingsList.py b/SettingsList.py index f02f8e6393..f34b70842c 100644 --- a/SettingsList.py +++ b/SettingsList.py @@ -3601,6 +3601,7 @@ class SettingInfos: gui_text = 'Misc. Hints', choices = { 'altar': 'Temple of Time Altar', + 'altar_child_oot': 'Temple of Time Altar Child OoT and SoT rewards', 'dampe_diary': "Dampé's Diary (Hookshot)", 'ganondorf': 'Ganondorf (Light Arrows)', 'warp_songs_and_owls': 'Warp Songs and Owls', @@ -3626,6 +3627,10 @@ class SettingInfos: Spiritual Stones (unless Maps and Compasses Give Information is enabled). + Reading the Temple of Time altar as a child will + tell you what rewards the Ocarina of Time and + the Song of Time lead to. + Reading the Temple of Time altar as adult will tell you the locations of the Medallions (unless Maps and Compasses Give Information From ed9d4131dfa93c5f6f89132e0db8d86e9a584d36 Mon Sep 17 00:00:00 2001 From: RawZ06 Date: Thu, 17 Jul 2025 20:24:32 +0200 Subject: [PATCH 3/7] Update misc hint ocarina of time and song of time with new misc dual hint system --- HintList.py | 23 ++++++++++- Hints.py | 61 ++++++++++++++++-------------- LocationList.py | 2 + SettingsList.py | 5 ++- World.py | 2 +- data/Glitched World/Overworld.json | 2 + data/World/Overworld.json | 2 + 7 files changed, 64 insertions(+), 33 deletions(-) diff --git a/HintList.py b/HintList.py index 99423c2636..c5b2ed0c3c 100644 --- a/HintList.py +++ b/HintList.py @@ -216,8 +216,8 @@ def tokens_required_by_settings(world: World) -> int: conditional_always: dict[str, Callable[[World], bool]] = { 'Market 10 Big Poes': lambda world: world.settings.big_poe_count > 3 and 'big_poes' not in world.settings.misc_hints, 'Deku Theater Mask of Truth': lambda world: not world.settings.complete_mask_quest and 'Mask of Truth' not in world.settings.shuffle_child_trade and 'mask_of_truth' not in world.settings.misc_hints, - 'Song from Ocarina of Time': lambda world: stones_required_by_settings(world) < 2, - 'HF Ocarina of Time Item': lambda world: stones_required_by_settings(world) < 2, + 'Song from Ocarina of Time': lambda world: stones_required_by_settings(world) < 2 and 'song_of_time' not in world.settings.misc_hints, + 'HF Ocarina of Time Item': lambda world: stones_required_by_settings(world) < 2 and 'ocarina_of_time' not in world.settings.misc_hints, 'Sheik in Kakariko': lambda world: medallions_required_by_settings(world) < 5, 'DMT Biggoron': lambda world: ('Claim Check' not in world.settings.adult_trade_start or len(world.settings.adult_trade_start) != 1) and not world.settings.adult_trade_shuffle, 'Kak 30 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 30 and '30_skulltulas' not in world.settings.misc_hints, @@ -1949,6 +1949,20 @@ def rainbow_bridge_hint_kind(world: World) -> str: '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", 'text_style': 0x03, }, + 'ocarina_of_time': { + 'id': 0x707A, + 'hint_location': 'HF Ocarina of Time Item Hint', + 'item_location': 'HF Ocarina of Time Item', + 'location_text': 'The object retrieved under the drawbridge is \x05\x42{item}\x05\x40.', + 'text_style': 0x20, + }, + 'song_of_time': { + 'id': 0x707A, + 'hint_location': 'Song from Ocarina of Time Hint', + 'item_location': 'Song from Ocarina of Time', + 'location_text': 'The song learned after the reunification of \x05\x41The Spiritual Stones\x05\x40 is \x05\x42{item}\x05\x40.', + 'text_style': 0x20, + } } # Adds capability for dual misc hints. Only used when neither or both hints are enabled, uses corresponding misc_location_hint_table entries if only one is enabled. @@ -1961,6 +1975,11 @@ def rainbow_bridge_hint_kind(world: World) -> str: 'location_fallback': '\x05\x42\x06\x3dForest Stage\x04\x01\x05\x40\x06\x14We are waiting to see your\x01\x06\x32beautiful face!\x01\x06\x28Win fabulous prizes!', 'text_style': 0x13, }, + ('ocarina_of_time', 'song_of_time'): { + 'id': 0x707A, + 'location_text': 'It is also written that reuniting \x05\x41The Spiritual Stones\x05\x40 leads to \x05\x42{item_1}\x05\x40 and \x05\x42{item_2}\x05\x40', + 'text_style': 0x20, + }, } # Separate table for goal names to avoid duplicates in the hint table. diff --git a/Hints.py b/Hints.py index c96904ee7b..257b3bf855 100644 --- a/Hints.py +++ b/Hints.py @@ -1667,7 +1667,8 @@ def build_altar_hints(world: World, messages: list[Message], include_rewards: bo child_text += get_hint('Spiritual Stone Text Start', world.settings.clearer_hints).text + '\x04' for (reward, color) in boss_rewards_spiritual_stones: child_text += build_boss_string(reward, color, world) - if 'altar_child_oot' in world.settings.misc_hints: + sot_oot_misc_hint = build_oot_sot_hints(world) + if sot_oot_misc_hint is not None: child_text += build_oot_sot_hints(world) child_text += '\x04' child_text += get_hint('Child Altar Text End', world.settings.clearer_hints).text @@ -1717,14 +1718,10 @@ def build_boss_string(reward: str, color: str, world: World) -> str: return str(text) + '\x04' def build_oot_sot_hints(world: World) -> str: - sot_location = world.get_location('Song from Ocarina of Time') - oot_location = world.get_location('HF Ocarina of Time Item') - - sot_item = "#" + get_hint(get_item_generic_name(sot_location.item), world.settings.clearer_hints).text + '# ' - oot_item = "#" + get_hint(get_item_generic_name(oot_location.item), world.settings.clearer_hints).text + '# ' - - string = f"It is also written that reuniting #The Spiritual Stones# leads to " + sot_item + " and " + oot_item + '' - + dual_data = misc_dual_hint_table.get(('ocarina_of_time', 'song_of_time')) + string = build_text_misc_dual_hints(world, dual_data, hint_type1='ocarina_of_time', hint_type2='song_of_time') + if string is None: + return None return str(GossipText(string, ['Yellow', 'Blue', 'Blue'], prefix='')) def build_bridge_reqs_string(world: World) -> str: @@ -1862,26 +1859,34 @@ def build_misc_location_hints(world: World, messages: list[Message]) -> None: def build_misc_dual_hints(world: World, messages: list[Message]) -> None: for (hint_type1, hint_type2), data in misc_dual_hint_table.items(): - item_1 = world.misc_hint_location_items[hint_type1] - item_2 = world.misc_hint_location_items[hint_type2] - if hint_type1 in world.settings.misc_hints and hint_type1 in world.misc_hint_location_items: - if hint_type2 in world.settings.misc_hints and hint_type2 in world.misc_hint_location_items: - text = data['location_text'].format( - item_1=get_hint(get_item_generic_name(item_1), world.settings.clearer_hints).text, - item_2=get_hint(get_item_generic_name(item_2), world.settings.clearer_hints).text, - ) - else: - text = misc_location_hint_table[hint_type1]['location_text'].format( - item=get_hint(get_item_generic_name(item_1), world.settings.clearer_hints).text, - ) + if hint_type1 == 'ocarina_of_time': + continue + + text = build_text_misc_dual_hints(world, data, hint_type1, hint_type2) + if text is not None: + update_message_by_id(messages, data['id'], str(GossipText(text, ['Green'], prefix='')), data['text_style']) + + +def build_text_misc_dual_hints(world: World, data, hint_type1: str, hint_type2: str): + item_1 = world.misc_hint_location_items[hint_type1] + item_2 = world.misc_hint_location_items[hint_type2] + if hint_type1 in world.settings.misc_hints and hint_type1 in world.misc_hint_location_items: + if hint_type2 in world.settings.misc_hints and hint_type2 in world.misc_hint_location_items: + return data['location_text'].format( + item_1=get_hint(get_item_generic_name(item_1), world.settings.clearer_hints).text, + item_2=get_hint(get_item_generic_name(item_2), world.settings.clearer_hints).text, + ) else: - if hint_type2 in world.settings.misc_hints and hint_type2 in world.misc_hint_location_items: - text = misc_location_hint_table[hint_type2]['location_text'].format( - item=get_hint(get_item_generic_name(item_2), world.settings.clearer_hints).text, - ) - else: - text = data['location_fallback'] - update_message_by_id(messages, data['id'], str(GossipText(text, ['Green'], prefix='')), data['text_style']) + return misc_location_hint_table[hint_type1]['location_text'].format( + item=get_hint(get_item_generic_name(item_1), world.settings.clearer_hints).text, + ) + else: + if hint_type2 in world.settings.misc_hints and hint_type2 in world.misc_hint_location_items: + return misc_location_hint_table[hint_type2]['location_text'].format( + item=get_hint(get_item_generic_name(item_2), world.settings.clearer_hints).text, + ) + else: + return data['location_fallback'] def get_raw_text(string: str) -> str: diff --git a/LocationList.py b/LocationList.py index b19553f7d1..032adc069c 100644 --- a/LocationList.py +++ b/LocationList.py @@ -2610,6 +2610,8 @@ def shop_address(shop_id: int, shelf_id: int) -> int: ("Market 10 Big Poes Hint", ("Hint", None, None, None, None, None)), ("Deku Theater Skull Mask Hint", ("Hint", None, None, None, None, None)), ("Deku Theater Mask of Truth Hint", ("Hint", None, None, None, None, None)), + ("HF Ocarina of Time Item Hint", ("Hint", None, None, None, None, None)), + ("Song from Ocarina of Time Hint", ("Hint", None, None, None, None, None)), ("Ganondorf Hint", ("Hint", None, None, None, None, None)), ]) diff --git a/SettingsList.py b/SettingsList.py index f34b70842c..03386ef124 100644 --- a/SettingsList.py +++ b/SettingsList.py @@ -3601,7 +3601,8 @@ class SettingInfos: gui_text = 'Misc. Hints', choices = { 'altar': 'Temple of Time Altar', - 'altar_child_oot': 'Temple of Time Altar Child OoT and SoT rewards', + 'ocarina_of_time': 'Ocarina of Time reward', + 'song_of_time': 'Song of Time', 'dampe_diary': "Dampé's Diary (Hookshot)", 'ganondorf': 'Ganondorf (Light Arrows)', 'warp_songs_and_owls': 'Warp Songs and Owls', @@ -3628,7 +3629,7 @@ class SettingInfos: Give Information is enabled). Reading the Temple of Time altar as a child will - tell you what rewards the Ocarina of Time and + tell you what rewards the Ocarina of Time or/and the Song of Time lead to. Reading the Temple of Time altar as adult diff --git a/World.py b/World.py index 95dd6599ca..8857df349b 100644 --- a/World.py +++ b/World.py @@ -11,7 +11,7 @@ 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, misc_dual_hint_table +from HintList import get_required_hints, misc_item_hint_table, misc_location_hint_table from Hints import HintArea, hint_dist_keys, hint_dist_files from Item import Item, ItemFactory, ItemInfo, make_event_item from ItemList import REWARD_COLORS diff --git a/data/Glitched World/Overworld.json b/data/Glitched World/Overworld.json index 880db61a18..8b7057418b 100644 --- a/data/Glitched World/Overworld.json +++ b/data/Glitched World/Overworld.json @@ -1487,6 +1487,8 @@ "locations": { "ToT Light Arrows Cutscene": "is_adult and can_trigger_lacs", "ToT Child Altar Hint": "is_child", + "HF Ocarina of Time Item Hint": "is_child", + "Song from Ocarina of Time Hint": "is_child", "ToT Adult Altar Hint": "is_adult" }, "exits": { diff --git a/data/World/Overworld.json b/data/World/Overworld.json index fe6fd4442e..7423eca009 100644 --- a/data/World/Overworld.json +++ b/data/World/Overworld.json @@ -1308,6 +1308,8 @@ "locations": { "ToT Light Arrows Cutscene": "is_adult and can_trigger_lacs", "ToT Child Altar Hint": "is_child", + "HF Ocarina of Time Item Hint": "is_child", + "Song from Ocarina of Time Hint": "is_child", "ToT Adult Altar Hint": "is_adult" }, "exits": { From 7761ef0d7bf15d075e9b5aa0ec40747288e6d27c Mon Sep 17 00:00:00 2001 From: RawZ06 Date: Thu, 17 Jul 2025 20:24:32 +0200 Subject: [PATCH 4/7] Use variable instead of recall function --- Hints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hints.py b/Hints.py index 257b3bf855..6ca60262e5 100644 --- a/Hints.py +++ b/Hints.py @@ -1669,7 +1669,7 @@ def build_altar_hints(world: World, messages: list[Message], include_rewards: bo child_text += build_boss_string(reward, color, world) sot_oot_misc_hint = build_oot_sot_hints(world) if sot_oot_misc_hint is not None: - child_text += build_oot_sot_hints(world) + child_text += sot_oot_misc_hint child_text += '\x04' child_text += get_hint('Child Altar Text End', world.settings.clearer_hints).text child_text += '\x0B' From 51c86bc552e71f9b91a8d0347356ee3586154c68 Mon Sep 17 00:00:00 2001 From: RawZ06 Date: Thu, 17 Jul 2025 20:24:32 +0200 Subject: [PATCH 5/7] Apply review suggestion, change typo altar hint --- HintList.py | 4 ++-- Hints.py | 5 ++--- SettingsList.py | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/HintList.py b/HintList.py index c5b2ed0c3c..990faeda10 100644 --- a/HintList.py +++ b/HintList.py @@ -1960,7 +1960,7 @@ def rainbow_bridge_hint_kind(world: World) -> str: 'id': 0x707A, 'hint_location': 'Song from Ocarina of Time Hint', 'item_location': 'Song from Ocarina of Time', - 'location_text': 'The song learned after the reunification of \x05\x41The Spiritual Stones\x05\x40 is \x05\x42{item}\x05\x40.', + 'location_text': 'The song learned after the reunification of the \x05\x41Spiritual Stones\x05\x40 is \x05\x42{item}\x05\x40.', 'text_style': 0x20, } } @@ -1977,7 +1977,7 @@ def rainbow_bridge_hint_kind(world: World) -> str: }, ('ocarina_of_time', 'song_of_time'): { 'id': 0x707A, - 'location_text': 'It is also written that reuniting \x05\x41The Spiritual Stones\x05\x40 leads to \x05\x42{item_1}\x05\x40 and \x05\x42{item_2}\x05\x40', + 'location_text': 'Reuniting the \x05\x41Spiritual Stones\x05\x40 leads to \x05\x42{item_1}\x05\x40 and \x05\x42{item_2}\x05\x40.', 'text_style': 0x20, }, } diff --git a/Hints.py b/Hints.py index 6ca60262e5..808cf23559 100644 --- a/Hints.py +++ b/Hints.py @@ -1863,11 +1863,10 @@ def build_misc_dual_hints(world: World, messages: list[Message]) -> None: continue text = build_text_misc_dual_hints(world, data, hint_type1, hint_type2) - if text is not None: - update_message_by_id(messages, data['id'], str(GossipText(text, ['Green'], prefix='')), data['text_style']) + update_message_by_id(messages, data['id'], str(GossipText(text, ['Green'], prefix='')), data['text_style']) -def build_text_misc_dual_hints(world: World, data, hint_type1: str, hint_type2: str): +def build_text_misc_dual_hints(world: World, data, hint_type1: str, hint_type2: str) -> str: item_1 = world.misc_hint_location_items[hint_type1] item_2 = world.misc_hint_location_items[hint_type2] if hint_type1 in world.settings.misc_hints and hint_type1 in world.misc_hint_location_items: diff --git a/SettingsList.py b/SettingsList.py index 03386ef124..afb9dc64a0 100644 --- a/SettingsList.py +++ b/SettingsList.py @@ -3600,9 +3600,9 @@ class SettingInfos: misc_hints = MultipleSelect( gui_text = 'Misc. Hints', choices = { - 'altar': 'Temple of Time Altar', - 'ocarina_of_time': 'Ocarina of Time reward', - 'song_of_time': 'Song of Time', + 'altar': 'Temple of Time Altar (Win Conditions)', + 'ocarina_of_time': 'Temple of Time Altar (Ocarina of Time)', + 'song_of_time': 'Temple of Time Altar (Song of Time)', 'dampe_diary': "Dampé's Diary (Hookshot)", 'ganondorf': 'Ganondorf (Light Arrows)', 'warp_songs_and_owls': 'Warp Songs and Owls', From c4d9a7c05ca18e9deac88def4004a407bebe6115 Mon Sep 17 00:00:00 2001 From: RawZ06 Date: Thu, 17 Jul 2025 20:24:32 +0200 Subject: [PATCH 6/7] Reword tooltip sentence for clarity --- SettingsList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SettingsList.py b/SettingsList.py index afb9dc64a0..0d92df0f7c 100644 --- a/SettingsList.py +++ b/SettingsList.py @@ -3629,8 +3629,8 @@ class SettingInfos: Give Information is enabled). Reading the Temple of Time altar as a child will - tell you what rewards the Ocarina of Time or/and - the Song of Time lead to. + tell you what item thrown by Zelda and what song + the Ocarina of Time teaches. Reading the Temple of Time altar as adult will tell you the locations of the Medallions From e287359f7dbeb65f54ee66b9cf13852f2961de9e Mon Sep 17 00:00:00 2001 From: RawZ06 Date: Thu, 17 Jul 2025 20:34:54 +0200 Subject: [PATCH 7/7] Remove useless whitespace --- SettingsList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SettingsList.py b/SettingsList.py index 0d92df0f7c..c95060bd79 100644 --- a/SettingsList.py +++ b/SettingsList.py @@ -3629,7 +3629,7 @@ class SettingInfos: Give Information is enabled). Reading the Temple of Time altar as a child will - tell you what item thrown by Zelda and what song + tell you what item thrown by Zelda and what song the Ocarina of Time teaches. Reading the Temple of Time altar as adult