| 
									
										
										
										
											2023-11-25 16:00:15 +01:00
										 |  |  | from typing import TYPE_CHECKING | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from BaseClasses import Location | 
					
						
							|  |  |  | from .data.hint_source import HINT_SOURCES_JSON | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if TYPE_CHECKING: | 
					
						
							|  |  |  |     from random import Random | 
					
						
							|  |  |  |     from . import LandstalkerWorld | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def generate_blurry_location_hint(location: Location, random: "Random"): | 
					
						
							|  |  |  |     cleaned_location_name = location.hint_text.lower().translate({ord(c): None for c in "(),:"}) | 
					
						
							|  |  |  |     cleaned_location_name.replace("-", " ") | 
					
						
							|  |  |  |     cleaned_location_name.replace("/", " ") | 
					
						
							|  |  |  |     cleaned_location_name.replace(".", " ") | 
					
						
							|  |  |  |     location_name_words = [w for w in cleaned_location_name.split(" ") if len(w) > 3] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     random_word_1 = "mysterious" | 
					
						
							|  |  |  |     random_word_2 = "place" | 
					
						
							|  |  |  |     if location_name_words: | 
					
						
							|  |  |  |         random_word_1 = random.choice(location_name_words) | 
					
						
							|  |  |  |         location_name_words.remove(random_word_1) | 
					
						
							|  |  |  |         if location_name_words: | 
					
						
							|  |  |  |             random_word_2 = random.choice(location_name_words) | 
					
						
							|  |  |  |     return [random_word_1, random_word_2] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def generate_lithograph_hint(world: "LandstalkerWorld"): | 
					
						
							|  |  |  |     hint_text = "It's barely readable:\n" | 
					
						
							|  |  |  |     jewel_items = world.jewel_items | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for item in jewel_items: | 
					
						
							| 
									
										
										
										
											2024-06-01 13:39:57 +02:00
										 |  |  |         if item.location is None: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 16:00:15 +01:00
										 |  |  |         # Jewel hints are composed of 4 'words' shuffled randomly: | 
					
						
							|  |  |  |         # - the name of the player whose world contains said jewel (if not ours) | 
					
						
							|  |  |  |         # - the color of the jewel (if relevant) | 
					
						
							|  |  |  |         # - two random words from the location name | 
					
						
							|  |  |  |         words = generate_blurry_location_hint(item.location, world.random) | 
					
						
							|  |  |  |         words[0] = words[0].upper() | 
					
						
							|  |  |  |         words[1] = words[1].upper() | 
					
						
							|  |  |  |         if len(jewel_items) < 6: | 
					
						
							|  |  |  |             # Add jewel color if we are not using generic jewels because jewel count is 6 or more | 
					
						
							|  |  |  |             words.append(item.name.split(" ")[0].upper()) | 
					
						
							|  |  |  |         if item.location.player != world.player: | 
					
						
							|  |  |  |             # Add player name if it's not in our own world | 
					
						
							| 
									
										
										
										
											2024-12-24 20:08:03 +01:00
										 |  |  |             player_name = world.multiworld.get_player_name(item.location.player) | 
					
						
							| 
									
										
										
										
											2023-11-25 16:00:15 +01:00
										 |  |  |             words.append(player_name.upper()) | 
					
						
							|  |  |  |         world.random.shuffle(words) | 
					
						
							|  |  |  |         hint_text += " ".join(words) + "\n" | 
					
						
							|  |  |  |     return hint_text.rstrip("\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def generate_random_hints(world: "LandstalkerWorld"): | 
					
						
							|  |  |  |     hints = {} | 
					
						
							|  |  |  |     hint_texts = [] | 
					
						
							|  |  |  |     random = world.random | 
					
						
							|  |  |  |     multiworld = world.multiworld | 
					
						
							|  |  |  |     this_player = world.player | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Exclude Life Stock from the hints as some of them are considered as progression for Fahl, but isn't really | 
					
						
							|  |  |  |     # exciting when hinted | 
					
						
							|  |  |  |     excluded_items = ["Life Stock", "EkeEke"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     progression_items = [item for item in multiworld.itempool if item.advancement and | 
					
						
							| 
									
										
										
										
											2024-06-01 13:39:57 +02:00
										 |  |  |                          item.name not in excluded_items and item.location is not None] | 
					
						
							| 
									
										
										
										
											2023-11-25 16:00:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     local_own_progression_items = [item for item in progression_items if item.player == this_player | 
					
						
							|  |  |  |                                    and item.location.player == this_player] | 
					
						
							|  |  |  |     remote_own_progression_items = [item for item in progression_items if item.player == this_player | 
					
						
							|  |  |  |                                     and item.location.player != this_player] | 
					
						
							|  |  |  |     local_unowned_progression_items = [item for item in progression_items if item.player != this_player | 
					
						
							|  |  |  |                                        and item.location.player == this_player] | 
					
						
							|  |  |  |     remote_unowned_progression_items = [item for item in progression_items if item.player != this_player | 
					
						
							|  |  |  |                                         and item.location.player != this_player] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Hint-type #1: Own progression item in own world | 
					
						
							|  |  |  |     for item in local_own_progression_items: | 
					
						
							|  |  |  |         region_hint = item.location.parent_region.hint_text | 
					
						
							|  |  |  |         hint_texts.append(f"I can sense {item.name} {region_hint}.") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Hint-type #2: Remote progression item in own world | 
					
						
							|  |  |  |     for item in local_unowned_progression_items: | 
					
						
							|  |  |  |         other_player = multiworld.get_player_name(item.player) | 
					
						
							|  |  |  |         own_local_region = item.location.parent_region.hint_text | 
					
						
							|  |  |  |         hint_texts.append(f"You might find something useful for {other_player} {own_local_region}. " | 
					
						
							|  |  |  |                           f"It is a {item.name}, to be precise.") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Hint-type #3: Own progression item in remote location | 
					
						
							|  |  |  |     for item in remote_own_progression_items: | 
					
						
							|  |  |  |         other_player = multiworld.get_player_name(item.location.player) | 
					
						
							|  |  |  |         if item.location.game == "Landstalker - The Treasures of King Nole": | 
					
						
							|  |  |  |             region_hint_name = item.location.parent_region.hint_text | 
					
						
							|  |  |  |             hint_texts.append(f"If you need {item.name}, tell {other_player} to look {region_hint_name}.") | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             [word_1, word_2] = generate_blurry_location_hint(item.location, random) | 
					
						
							|  |  |  |             if word_1 == "mysterious" and word_2 == "place": | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             hint_texts.append(f"Looking for {item.name}? I read something about {other_player}'s world... " | 
					
						
							|  |  |  |                               f"Does \"{word_1} {word_2}\" remind you anything?") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Hint-type #4: Remote progression item in remote location | 
					
						
							|  |  |  |     for item in remote_unowned_progression_items: | 
					
						
							|  |  |  |         owner_name = multiworld.get_player_name(item.player) | 
					
						
							|  |  |  |         if item.location.player == item.player: | 
					
						
							|  |  |  |             world_name = "their own world" | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             world_name = f"{multiworld.get_player_name(item.location.player)}'s world" | 
					
						
							|  |  |  |         [word_1, word_2] = generate_blurry_location_hint(item.location, random) | 
					
						
							|  |  |  |         if word_1 == "mysterious" and word_2 == "place": | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         hint_texts.append(f"I once found {owner_name}'s {item.name} in {world_name}. " | 
					
						
							|  |  |  |                           f"I remember \"{word_1} {word_2}\"... Does that make any sense?") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Hint-type #5: Jokes | 
					
						
							|  |  |  |     other_player_names = [multiworld.get_player_name(player) for player in multiworld.player_ids if | 
					
						
							|  |  |  |                           player != this_player] | 
					
						
							|  |  |  |     if other_player_names: | 
					
						
							|  |  |  |         random_player_name = random.choice(other_player_names) | 
					
						
							|  |  |  |         hint_texts.append(f"{random_player_name}'s world is objectively better than yours.") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hint_texts.append(f"Have you found all of the {len(multiworld.itempool)} items in this universe?") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     local_progression_item_count = len(local_own_progression_items) + len(local_unowned_progression_items) | 
					
						
							|  |  |  |     remote_progression_item_count = len(remote_own_progression_items) + len(remote_unowned_progression_items) | 
					
						
							|  |  |  |     percent = (local_progression_item_count / (local_progression_item_count + remote_progression_item_count)) * 100 | 
					
						
							|  |  |  |     hint_texts.append(f"Did you know that your world contains {int(percent)} percent of all progression items?") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Shuffle hint texts and hint source names, and pair the two of those together | 
					
						
							|  |  |  |     hint_texts = list(set(hint_texts)) | 
					
						
							|  |  |  |     random.shuffle(hint_texts) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-10 16:35:58 +01:00
										 |  |  |     hint_count = min(world.options.hint_count.value, len(hint_texts)) | 
					
						
							| 
									
										
										
										
											2023-11-25 16:00:15 +01:00
										 |  |  |     del hint_texts[hint_count:] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hint_source_names = [source["description"] for source in HINT_SOURCES_JSON if | 
					
						
							|  |  |  |                          source["description"].startswith("Foxy")] | 
					
						
							|  |  |  |     random.shuffle(hint_source_names) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for i in range(hint_count): | 
					
						
							|  |  |  |         hints[hint_source_names[i]] = hint_texts[i] | 
					
						
							|  |  |  |     return hints |