From be9d75f75b5469742b7eb0474f0de6a75b281e96 Mon Sep 17 00:00:00 2001 From: Dinopony Date: Sat, 25 Nov 2023 16:00:15 +0100 Subject: [PATCH] Landstalker: implement new game (#1808) Co-authored-by: Anthony Demarcy Co-authored-by: Phar --- README.md | 1 + docs/CODEOWNERS | 3 + worlds/landstalker/Hints.py | 140 ++ worlds/landstalker/Items.py | 105 + worlds/landstalker/Locations.py | 53 + worlds/landstalker/Options.py | 228 ++ worlds/landstalker/Regions.py | 118 + worlds/landstalker/Rules.py | 134 ++ worlds/landstalker/__init__.py | 262 +++ worlds/landstalker/data/hint_source.py | 1989 ++++++++++++++++ worlds/landstalker/data/item_source.py | 2017 +++++++++++++++++ worlds/landstalker/data/world_node.py | 411 ++++ worlds/landstalker/data/world_path.py | 446 ++++ worlds/landstalker/data/world_region.py | 299 +++ .../landstalker/data/world_teleport_tree.py | 62 + ...andstalker - The Treasures of King Nole.md | 60 + .../landstalker/docs/landstalker_setup_en.md | 119 + worlds/landstalker/docs/ls_guide_ap.png | Bin 0 -> 2283 bytes worlds/landstalker/docs/ls_guide_client.png | Bin 0 -> 86096 bytes worlds/landstalker/docs/ls_guide_emu.png | Bin 0 -> 2598 bytes worlds/landstalker/docs/ls_guide_rom.png | Bin 0 -> 3951 bytes 21 files changed, 6447 insertions(+) create mode 100644 worlds/landstalker/Hints.py create mode 100644 worlds/landstalker/Items.py create mode 100644 worlds/landstalker/Locations.py create mode 100644 worlds/landstalker/Options.py create mode 100644 worlds/landstalker/Regions.py create mode 100644 worlds/landstalker/Rules.py create mode 100644 worlds/landstalker/__init__.py create mode 100644 worlds/landstalker/data/hint_source.py create mode 100644 worlds/landstalker/data/item_source.py create mode 100644 worlds/landstalker/data/world_node.py create mode 100644 worlds/landstalker/data/world_path.py create mode 100644 worlds/landstalker/data/world_region.py create mode 100644 worlds/landstalker/data/world_teleport_tree.py create mode 100644 worlds/landstalker/docs/en_Landstalker - The Treasures of King Nole.md create mode 100644 worlds/landstalker/docs/landstalker_setup_en.md create mode 100644 worlds/landstalker/docs/ls_guide_ap.png create mode 100644 worlds/landstalker/docs/ls_guide_client.png create mode 100644 worlds/landstalker/docs/ls_guide_emu.png create mode 100644 worlds/landstalker/docs/ls_guide_rom.png diff --git a/README.md b/README.md index b51fe00f9ac2..3508dd16095c 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Currently, the following games are supported: * DOOM II * Shivers * Heretic +* Landstalker: The Treasures of King Nole For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index c589b1333c9b..0764fa927464 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -67,6 +67,9 @@ # Kingdom Hearts 2 /worlds/kh2/ @JaredWeakStrike +# Landstalker: The Treasures of King Nole +/worlds/landstalker/ @Dinopony + # Lingo /worlds/lingo/ @hatkirby diff --git a/worlds/landstalker/Hints.py b/worlds/landstalker/Hints.py new file mode 100644 index 000000000000..93274f1d68bb --- /dev/null +++ b/worlds/landstalker/Hints.py @@ -0,0 +1,140 @@ +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: + # 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 + player_name = world.multiworld.get_player_name(world.player) + 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 + item.name not in excluded_items] + + 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) + + hint_count = world.options.hint_count.value + 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 diff --git a/worlds/landstalker/Items.py b/worlds/landstalker/Items.py new file mode 100644 index 000000000000..ad7efa1cb27a --- /dev/null +++ b/worlds/landstalker/Items.py @@ -0,0 +1,105 @@ +from typing import Dict, List, NamedTuple + +from BaseClasses import Item, ItemClassification + +BASE_ITEM_ID = 4000 + + +class LandstalkerItem(Item): + game: str = "Landstalker - The Treasures of King Nole" + price_in_shops: int + + +class LandstalkerItemData(NamedTuple): + id: int + classification: ItemClassification + price_in_shops: int + quantity: int = 1 + + +item_table: Dict[str, LandstalkerItemData] = { + "EkeEke": LandstalkerItemData(0, ItemClassification.filler, 20, 0), # Variable amount + "Magic Sword": LandstalkerItemData(1, ItemClassification.useful, 300), + "Sword of Ice": LandstalkerItemData(2, ItemClassification.useful, 300), + "Thunder Sword": LandstalkerItemData(3, ItemClassification.useful, 500), + "Sword of Gaia": LandstalkerItemData(4, ItemClassification.progression, 300), + "Fireproof": LandstalkerItemData(5, ItemClassification.progression, 150), + "Iron Boots": LandstalkerItemData(6, ItemClassification.progression, 150), + "Healing Boots": LandstalkerItemData(7, ItemClassification.useful, 300), + "Snow Spikes": LandstalkerItemData(8, ItemClassification.progression, 400), + "Steel Breast": LandstalkerItemData(9, ItemClassification.useful, 200), + "Chrome Breast": LandstalkerItemData(10, ItemClassification.useful, 350), + "Shell Breast": LandstalkerItemData(11, ItemClassification.useful, 500), + "Hyper Breast": LandstalkerItemData(12, ItemClassification.useful, 700), + "Mars Stone": LandstalkerItemData(13, ItemClassification.useful, 150), + "Moon Stone": LandstalkerItemData(14, ItemClassification.useful, 150), + "Saturn Stone": LandstalkerItemData(15, ItemClassification.useful, 200), + "Venus Stone": LandstalkerItemData(16, ItemClassification.useful, 300), + # Awakening Book: 17 + "Detox Grass": LandstalkerItemData(18, ItemClassification.filler, 25, 9), + "Statue of Gaia": LandstalkerItemData(19, ItemClassification.filler, 75, 12), + "Golden Statue": LandstalkerItemData(20, ItemClassification.filler, 150, 10), + "Mind Repair": LandstalkerItemData(21, ItemClassification.filler, 25, 7), + "Casino Ticket": LandstalkerItemData(22, ItemClassification.progression, 50), + "Axe Magic": LandstalkerItemData(23, ItemClassification.progression, 400), + "Blue Ribbon": LandstalkerItemData(24, ItemClassification.filler, 50), + "Buyer Card": LandstalkerItemData(25, ItemClassification.progression, 150), + "Lantern": LandstalkerItemData(26, ItemClassification.progression, 200), + "Garlic": LandstalkerItemData(27, ItemClassification.progression, 150, 2), + "Anti Paralyze": LandstalkerItemData(28, ItemClassification.filler, 20, 7), + "Statue of Jypta": LandstalkerItemData(29, ItemClassification.useful, 250), + "Sun Stone": LandstalkerItemData(30, ItemClassification.progression, 300), + "Armlet": LandstalkerItemData(31, ItemClassification.progression, 300), + "Einstein Whistle": LandstalkerItemData(32, ItemClassification.progression, 200), + "Blue Jewel": LandstalkerItemData(33, ItemClassification.progression, 500, 0), # Detox Book in base game + "Yellow Jewel": LandstalkerItemData(34, ItemClassification.progression, 500, 0), # AntiCurse Book in base game + # Record Book: 35 + # Spell Book: 36 + # Hotel Register: 37 + # Island Map: 38 + "Lithograph": LandstalkerItemData(39, ItemClassification.progression, 250), + "Red Jewel": LandstalkerItemData(40, ItemClassification.progression, 500, 0), + "Pawn Ticket": LandstalkerItemData(41, ItemClassification.useful, 200, 4), + "Purple Jewel": LandstalkerItemData(42, ItemClassification.progression, 500, 0), + "Gola's Eye": LandstalkerItemData(43, ItemClassification.progression, 400), + "Death Statue": LandstalkerItemData(44, ItemClassification.filler, 150), + "Dahl": LandstalkerItemData(45, ItemClassification.filler, 100, 18), + "Restoration": LandstalkerItemData(46, ItemClassification.filler, 40, 9), + "Logs": LandstalkerItemData(47, ItemClassification.progression, 100, 2), + "Oracle Stone": LandstalkerItemData(48, ItemClassification.progression, 250), + "Idol Stone": LandstalkerItemData(49, ItemClassification.progression, 200), + "Key": LandstalkerItemData(50, ItemClassification.progression, 150), + "Safety Pass": LandstalkerItemData(51, ItemClassification.progression, 250), + "Green Jewel": LandstalkerItemData(52, ItemClassification.progression, 500, 0), # No52 in base game + "Bell": LandstalkerItemData(53, ItemClassification.useful, 200), + "Short Cake": LandstalkerItemData(54, ItemClassification.useful, 250), + "Gola's Nail": LandstalkerItemData(55, ItemClassification.progression, 800), + "Gola's Horn": LandstalkerItemData(56, ItemClassification.progression, 800), + "Gola's Fang": LandstalkerItemData(57, ItemClassification.progression, 800), + # Broad Sword: 58 + # Leather Breast: 59 + # Leather Boots: 60 + # No Ring: 61 + "Life Stock": LandstalkerItemData(62, ItemClassification.filler, 250, 0), # Variable amount + "No Item": LandstalkerItemData(63, ItemClassification.filler, 0, 0), + "1 Gold": LandstalkerItemData(64, ItemClassification.filler, 1), + "20 Golds": LandstalkerItemData(65, ItemClassification.filler, 20, 15), + "50 Golds": LandstalkerItemData(66, ItemClassification.filler, 50, 7), + "100 Golds": LandstalkerItemData(67, ItemClassification.filler, 100, 5), + "200 Golds": LandstalkerItemData(68, ItemClassification.useful, 200, 2), + + "Progressive Armor": LandstalkerItemData(69, ItemClassification.useful, 250, 0), + "Kazalt Jewel": LandstalkerItemData(70, ItemClassification.progression, 500, 0) +} + + +def get_weighted_filler_item_names(): + weighted_item_names: List[str] = [] + for name, data in item_table.items(): + if data.classification == ItemClassification.filler: + weighted_item_names += [name for _ in range(data.quantity)] + return weighted_item_names + + +def build_item_name_to_id_table(): + return {name: data.id + BASE_ITEM_ID for name, data in item_table.items()} diff --git a/worlds/landstalker/Locations.py b/worlds/landstalker/Locations.py new file mode 100644 index 000000000000..5e42fbecda72 --- /dev/null +++ b/worlds/landstalker/Locations.py @@ -0,0 +1,53 @@ +from typing import Dict, Optional + +from BaseClasses import Location +from .Regions import LandstalkerRegion +from .data.item_source import ITEM_SOURCES_JSON + +BASE_LOCATION_ID = 4000 +BASE_GROUND_LOCATION_ID = BASE_LOCATION_ID + 256 +BASE_SHOP_LOCATION_ID = BASE_GROUND_LOCATION_ID + 30 +BASE_REWARD_LOCATION_ID = BASE_SHOP_LOCATION_ID + 50 + + +class LandstalkerLocation(Location): + game: str = "Landstalker - The Treasures of King Nole" + type_string: str + price: int = 0 + + def __init__(self, player: int, name: str, location_id: Optional[int], region: LandstalkerRegion, type_string: str): + super().__init__(player, name, location_id, region) + self.type_string = type_string + + +def create_locations(player: int, regions_table: Dict[str, LandstalkerRegion], name_to_id_table: Dict[str, int]): + # Create real locations from the data inside the corresponding JSON file + for data in ITEM_SOURCES_JSON: + region_id = data["nodeId"] + region = regions_table[region_id] + new_location = LandstalkerLocation(player, data["name"], name_to_id_table[data["name"]], region, data["type"]) + region.locations.append(new_location) + + # Create a specific end location that will contain a fake win-condition item + end_location = LandstalkerLocation(player, "End", None, regions_table["end"], "reward") + regions_table["end"].locations.append(end_location) + + +def build_location_name_to_id_table(): + location_name_to_id_table = {} + + for data in ITEM_SOURCES_JSON: + if data["type"] == "chest": + location_id = BASE_LOCATION_ID + int(data["chestId"]) + elif data["type"] == "ground": + location_id = BASE_GROUND_LOCATION_ID + int(data["groundItemId"]) + elif data["type"] == "shop": + location_id = BASE_SHOP_LOCATION_ID + int(data["shopItemId"]) + else: # if data["type"] == "reward": + location_id = BASE_REWARD_LOCATION_ID + int(data["rewardId"]) + location_name_to_id_table[data["name"]] = location_id + + # Win condition location ID + location_name_to_id_table["Gola"] = BASE_REWARD_LOCATION_ID + 10 + + return location_name_to_id_table diff --git a/worlds/landstalker/Options.py b/worlds/landstalker/Options.py new file mode 100644 index 000000000000..65ffd2c1f31e --- /dev/null +++ b/worlds/landstalker/Options.py @@ -0,0 +1,228 @@ +from dataclasses import dataclass + +from Options import Choice, DeathLink, DefaultOnToggle, PerGameCommonOptions, Range, Toggle + + +class LandstalkerGoal(Choice): + """ + The goal to accomplish in order to complete the seed. + - Beat Gola: beat the usual final boss (same as vanilla) + - Reach Kazalt: find the jewels and take the teleporter to Kazalt + - Beat Dark Nole: the door to King Nole's fight brings you into a final dungeon with an absurdly hard boss you have + to beat to win the game + """ + display_name = "Goal" + + option_beat_gola = 0 + option_reach_kazalt = 1 + option_beat_dark_nole = 2 + + default = 0 + + +class JewelCount(Range): + """ + Determines the number of jewels to find to be able to reach Kazalt. + """ + display_name = "Jewel Count" + range_start = 0 + range_end = 9 + default = 5 + + +class ProgressiveArmors(DefaultOnToggle): + """ + When obtaining an armor, you get the next armor tier instead of getting the specific armor tier that was + placed here by randomization. Enabling this provides a smoother progression. + """ + display_name = "Progressive Armors" + + +class UseRecordBook(DefaultOnToggle): + """ + Gives a Record Book item in starting inventory, allowing to save the game anywhere. + This makes the game significantly less frustrating and enables interesting save-scumming strategies in some places. + """ + display_name = "Use Record Book" + + +class UseSpellBook(DefaultOnToggle): + """ + Gives a Spell Book item in starting inventory, allowing to warp back to the starting location at any time. + This prevents any kind of softlock and makes the world easier to explore. + """ + display_name = "Use Spell Book" + + +class EnsureEkeEkeInShops(DefaultOnToggle): + """ + Ensures an EkeEke will always be for sale in one shop per region in the game. + Disabling this can lead to frustrating situations where you cannot refill your health items and might get locked. + """ + display_name = "Ensure EkeEke in Shops" + + +class RemoveGumiBoulder(Toggle): + """ + Removes the boulder between Gumi and Ryuma, which is usually a one-way path. + This makes the vanilla early game (Massan, Gumi...) more easily accessible when starting outside it. + """ + display_name = "Remove Boulder After Gumi" + + +class EnemyJumpingInLogic(Toggle): + """ + Adds jumping on enemies' heads as a logical rule. + This gives access to Mountainous Area from Lake Shrine sector and to the cliff chest behind a magic tree near Mir Tower. + These tricks not being easy, you should leave this disabled until practiced. + """ + display_name = "Enemy Jumping in Logic" + + +class TreeCuttingGlitchInLogic(Toggle): + """ + Adds tree-cutting glitch as a logical rule, enabling access to both chests behind magic trees in Mir Tower Sector + without having Axe Magic. + """ + display_name = "Tree-cutting Glitch in Logic" + + +class DamageBoostingInLogic(Toggle): + """ + Adds damage boosting as a logical rule, removing any requirements involving Iron Boots or Fireproof Boots. + Who doesn't like walking on spikes and lava? + """ + display_name = "Damage Boosting in Logic" + + +class WhistleUsageBehindTrees(DefaultOnToggle): + """ + In Greenmaze, Einstein Whistle can only be used to call Cutter from the intended side by default. + Enabling this allows using Einstein Whistle from both sides of the magic trees. + This is only useful in seeds starting in the "waterfall" spawn region or where teleportation trees are made open from the start. + """ + display_name = "Allow Using Einstein Whistle Behind Trees" + + +class SpawnRegion(Choice): + """ + List of spawn locations that can be picked by the randomizer. + It is advised to keep Massan as your spawn location for your first few seeds. + Picking a late-game location can make the seed significantly harder, both for logic and combat. + """ + display_name = "Starting Region" + + option_massan = 0 + option_gumi = 1 + option_kado = 2 + option_waterfall = 3 + option_ryuma = 4 + option_mercator = 5 + option_verla = 6 + option_greenmaze = 7 + option_destel = 8 + + default = 0 + + +class TeleportTreeRequirements(Choice): + """ + Determines the requirements to be able to use a teleport tree pair. + - None: All teleport trees are available right from the start + - Clear Tibor: Tibor needs to be cleared before unlocking any tree + - Visit Trees: Both trees from a tree pair need to be visited to teleport between them + Vanilla behavior is "Clear Tibor And Visit Trees" + """ + display_name = "Teleportation Trees Requirements" + + option_none = 0 + option_clear_tibor = 1 + option_visit_trees = 2 + option_clear_tibor_and_visit_trees = 3 + + default = 3 + + +class ShuffleTrees(Toggle): + """ + If enabled, all teleportation trees will be shuffled into new pairs. + """ + display_name = "Shuffle Teleportation Trees" + + +class ReviveUsingEkeeke(DefaultOnToggle): + """ + In the vanilla game, when you die, you are automatically revived by Friday using an EkeEke. + This setting allows disabling this feature, making the game extremely harder. + USE WITH CAUTION! + """ + display_name = "Revive Using EkeEke" + + +class ShopPricesFactor(Range): + """ + Applies a percentage factor on all prices in shops. Having higher prices can lead to a bit of gold farming, which + can make seeds longer but also sometimes more frustrating. + """ + display_name = "Shop Prices Factor (%)" + range_start = 50 + range_end = 200 + default = 100 + + +class CombatDifficulty(Choice): + """ + Determines the overall combat difficulty in the game by modifying both monsters HP & damage. + - Peaceful: 50% HP & damage + - Easy: 75% HP & damage + - Normal: 100% HP & damage + - Hard: 140% HP & damage + - Insane: 200% HP & damage + """ + display_name = "Combat Difficulty" + + option_peaceful = 0 + option_easy = 1 + option_normal = 2 + option_hard = 3 + option_insane = 4 + + default = 2 + + +class HintCount(Range): + """ + Determines the number of Foxy NPCs that will be scattered across the world, giving various types of hints + """ + display_name = "Hint Count" + range_start = 0 + range_end = 25 + default = 12 + + +@dataclass +class LandstalkerOptions(PerGameCommonOptions): + goal: LandstalkerGoal + spawn_region: SpawnRegion + jewel_count: JewelCount + progressive_armors: ProgressiveArmors + use_record_book: UseRecordBook + use_spell_book: UseSpellBook + + shop_prices_factor: ShopPricesFactor + combat_difficulty: CombatDifficulty + + teleport_tree_requirements: TeleportTreeRequirements + shuffle_trees: ShuffleTrees + + ensure_ekeeke_in_shops: EnsureEkeEkeInShops + remove_gumi_boulder: RemoveGumiBoulder + allow_whistle_usage_behind_trees: WhistleUsageBehindTrees + handle_damage_boosting_in_logic: DamageBoostingInLogic + handle_enemy_jumping_in_logic: EnemyJumpingInLogic + handle_tree_cutting_glitch_in_logic: TreeCuttingGlitchInLogic + + hint_count: HintCount + + revive_using_ekeeke: ReviveUsingEkeeke + death_link: DeathLink diff --git a/worlds/landstalker/Regions.py b/worlds/landstalker/Regions.py new file mode 100644 index 000000000000..21704194f157 --- /dev/null +++ b/worlds/landstalker/Regions.py @@ -0,0 +1,118 @@ +from typing import Dict, List, NamedTuple, Optional, TYPE_CHECKING + +from BaseClasses import MultiWorld, Region +from .data.world_node import WORLD_NODES_JSON +from .data.world_path import WORLD_PATHS_JSON +from .data.world_region import WORLD_REGIONS_JSON +from .data.world_teleport_tree import WORLD_TELEPORT_TREES_JSON + +if TYPE_CHECKING: + from . import LandstalkerWorld + + +class LandstalkerRegion(Region): + code: str + + def __init__(self, code: str, name: str, player: int, multiworld: MultiWorld, hint: Optional[str] = None): + super().__init__(name, player, multiworld, hint) + self.code = code + + +class LandstalkerRegionData(NamedTuple): + locations: Optional[List[str]] + region_exits: Optional[List[str]] + + +def create_regions(world: "LandstalkerWorld"): + regions_table: Dict[str, LandstalkerRegion] = {} + multiworld = world.multiworld + player = world.player + + # Create the hardcoded starting "Menu" region + menu_region = LandstalkerRegion("menu", "Menu", player, multiworld) + regions_table["menu"] = menu_region + multiworld.regions.append(menu_region) + + # Create regions from world_nodes + for code, region_data in WORLD_NODES_JSON.items(): + random_hint_name = None + if "hints" in region_data: + random_hint_name = multiworld.random.choice(region_data["hints"]) + region = LandstalkerRegion(code, region_data["name"], player, multiworld, random_hint_name) + regions_table[code] = region + multiworld.regions.append(region) + + # Create exits/entrances from world_paths + for data in WORLD_PATHS_JSON: + two_way = data["twoWay"] if "twoWay" in data else False + create_entrance(data["fromId"], data["toId"], two_way, regions_table) + + # Create a path between the fake Menu location and the starting location + starting_region = get_starting_region(world, regions_table) + menu_region.connect(starting_region, f"menu -> {starting_region.code}") + + add_specific_paths(world, regions_table) + + return regions_table + + +def add_specific_paths(world: "LandstalkerWorld", regions_table: Dict[str, LandstalkerRegion]): + # If Gumi boulder is removed, add a path from "route_gumi_ryuma" to "gumi" + if world.options.remove_gumi_boulder == 1: + create_entrance("route_gumi_ryuma", "gumi", False, regions_table) + + # If enemy jumping is in logic, Mountainous Area can be reached from route to Lake Shrine by doing a "ghost jump" + # at crossroads map + if world.options.handle_enemy_jumping_in_logic == 1: + create_entrance("route_lake_shrine", "route_lake_shrine_cliff", False, regions_table) + + # If using Einstein Whistle behind trees is allowed, add a new logic path there to reflect that change + if world.options.allow_whistle_usage_behind_trees == 1: + create_entrance("greenmaze_post_whistle", "greenmaze_pre_whistle", False, regions_table) + + +def create_entrance(from_id: str, to_id: str, two_way: bool, regions_table: Dict[str, LandstalkerRegion]): + created_entrances = [] + + name = from_id + " -> " + to_id + from_region = regions_table[from_id] + to_region = regions_table[to_id] + + created_entrances.append(from_region.connect(to_region, name)) + + if two_way: + reverse_name = to_id + " -> " + from_id + created_entrances.append(to_region.connect(from_region, reverse_name)) + + return created_entrances + + +def get_starting_region(world: "LandstalkerWorld", regions_table: Dict[str, LandstalkerRegion]): + # Most spawn locations have the same name as the region they are bound to, but a few vary. + spawn_id = world.options.spawn_region.current_key + if spawn_id == "waterfall": + return regions_table["greenmaze_post_whistle"] + elif spawn_id == "kado": + return regions_table["route_gumi_ryuma"] + elif spawn_id == "greenmaze": + return regions_table["greenmaze_pre_whistle"] + return regions_table[spawn_id] + + +def get_darkenable_regions(): + return {data["name"]: data["nodeIds"] for data in WORLD_REGIONS_JSON if "darkMapIds" in data} + + +def load_teleport_trees(): + pairs = [] + for pair in WORLD_TELEPORT_TREES_JSON: + first_tree = { + 'name': pair[0]["name"], + 'region': pair[0]["nodeId"] + } + second_tree = { + 'name': pair[1]["name"], + 'region': pair[1]["nodeId"] + } + pairs.append([first_tree, second_tree]) + return pairs diff --git a/worlds/landstalker/Rules.py b/worlds/landstalker/Rules.py new file mode 100644 index 000000000000..51357c9480b0 --- /dev/null +++ b/worlds/landstalker/Rules.py @@ -0,0 +1,134 @@ +from typing import List, TYPE_CHECKING + +from BaseClasses import CollectionState +from .data.world_path import WORLD_PATHS_JSON +from .Locations import LandstalkerLocation +from .Regions import LandstalkerRegion + +if TYPE_CHECKING: + from . import LandstalkerWorld + + +def _landstalker_has_visited_regions(state: CollectionState, player: int, regions): + return all([state.can_reach(region, None, player) for region in regions]) + + +def _landstalker_has_health(state: CollectionState, player: int, health): + return state.has("Life Stock", player, health) + + +# multiworld: MultiWorld, player: int, regions_table: Dict[str, Region], dark_region_ids: List[str] +def create_rules(world: "LandstalkerWorld"): + # Item & exploration requirements to take paths + add_path_requirements(world) + add_specific_path_requirements(world) + + # Location rules to forbid some item types depending on location types + add_location_rules(world) + + # Win condition + world.multiworld.completion_condition[world.player] = lambda state: state.has("King Nole's Treasure", world.player) + + +# multiworld: MultiWorld, player: int, regions_table: Dict[str, Region], +# dark_region_ids: List[str] +def add_path_requirements(world: "LandstalkerWorld"): + for data in WORLD_PATHS_JSON: + name = data["fromId"] + " -> " + data["toId"] + + # Determine required items to reach this region + required_items = data["requiredItems"] if "requiredItems" in data else [] + if "itemsPlacedWhenCrossing" in data: + required_items += data["itemsPlacedWhenCrossing"] + + if data["toId"] in world.dark_region_ids: + # Make Lantern required to reach the randomly selected dark regions + required_items.append("Lantern") + if world.options.handle_damage_boosting_in_logic: + # If damage boosting is handled in logic, remove all iron boots & fireproof requirements + required_items = [item for item in required_items if item != "Iron Boots" and item != "Fireproof"] + + # Determine required other visited regions to reach this region + required_region_ids = data["requiredNodes"] if "requiredNodes" in data else [] + required_regions = [world.regions_table[region_id] for region_id in required_region_ids] + + if not (required_items or required_regions): + continue + + # Create the rule lambda using those requirements + access_rule = make_path_requirement_lambda(world.player, required_items, required_regions) + world.multiworld.get_entrance(name, world.player).access_rule = access_rule + + # If two-way, also apply the rule to the opposite path + if "twoWay" in data and data["twoWay"] is True: + reverse_name = data["toId"] + " -> " + data["fromId"] + world.multiworld.get_entrance(reverse_name, world.player).access_rule = access_rule + + +def add_specific_path_requirements(world: "LandstalkerWorld"): + multiworld = world.multiworld + player = world.player + + # Make the jewels required to reach Kazalt + jewel_count = world.options.jewel_count.value + path_to_kazalt = multiworld.get_entrance("king_nole_cave -> kazalt", player) + if jewel_count < 6: + # 5- jewels => the player needs to find as many uniquely named jewel items + required_jewels = ["Red Jewel", "Purple Jewel", "Green Jewel", "Blue Jewel", "Yellow Jewel"] + del required_jewels[jewel_count:] + path_to_kazalt.access_rule = make_path_requirement_lambda(player, required_jewels, []) + else: + # 6+ jewels => the player needs to find as many "Kazalt Jewel" items + path_to_kazalt.access_rule = lambda state: state.has("Kazalt Jewel", player, jewel_count) + + # If enemy jumping is enabled, Mir Tower sector first tree can be bypassed to reach the elevated ledge + if world.options.handle_enemy_jumping_in_logic == 1: + remove_requirements_for(world, "mir_tower_sector -> mir_tower_sector_tree_ledge") + + # Both trees in Mir Tower sector can be abused using tree cutting glitch + if world.options.handle_tree_cutting_glitch_in_logic == 1: + remove_requirements_for(world, "mir_tower_sector -> mir_tower_sector_tree_ledge") + remove_requirements_for(world, "mir_tower_sector -> mir_tower_sector_tree_coast") + + # If Whistle can be used from behind the trees, it adds a new path that requires the whistle as well + if world.options.allow_whistle_usage_behind_trees == 1: + entrance = multiworld.get_entrance("greenmaze_post_whistle -> greenmaze_pre_whistle", player) + entrance.access_rule = make_path_requirement_lambda(player, ["Einstein Whistle"], []) + + +def make_path_requirement_lambda(player: int, required_items: List[str], required_regions: List[LandstalkerRegion]): + """ + Lambdas are created in a for loop, so values need to be captured + """ + return lambda state: \ + state.has_all(set(required_items), player) and _landstalker_has_visited_regions(state, player, required_regions) + + +def make_shop_location_requirement_lambda(player: int, location: LandstalkerLocation): + """ + Lambdas are created in a for loop, so values need to be captured + """ + # Prevent local golds in shops, as well as duplicates + other_locations_in_shop = [loc for loc in location.parent_region.locations if loc != location] + return lambda item: \ + item.player != player \ + or (" Gold" not in item.name + and item.name not in [loc.item.name for loc in other_locations_in_shop if loc.item is not None]) + + +def remove_requirements_for(world: "LandstalkerWorld", entrance_name: str): + entrance = world.multiworld.get_entrance(entrance_name, world.player) + entrance.access_rule = lambda state: True + + +def add_location_rules(world: "LandstalkerWorld"): + location: LandstalkerLocation + for location in world.multiworld.get_locations(world.player): + if location.type_string == "ground": + location.item_rule = lambda item: not (item.player == world.player and " Gold" in item.name) + elif location.type_string == "shop": + location.item_rule = make_shop_location_requirement_lambda(world.player, location) + + # Add a special rule for Fahl + fahl_location = world.multiworld.get_location("Mercator: Fahl's dojo challenge reward", world.player) + fahl_location.access_rule = lambda state: _landstalker_has_health(state, world.player, 15) diff --git a/worlds/landstalker/__init__.py b/worlds/landstalker/__init__.py new file mode 100644 index 000000000000..baa1deb620a4 --- /dev/null +++ b/worlds/landstalker/__init__.py @@ -0,0 +1,262 @@ +from typing import ClassVar, Set + +from BaseClasses import LocationProgressType, Tutorial +from worlds.AutoWorld import WebWorld, World +from .Hints import * +from .Items import * +from .Locations import * +from .Options import JewelCount, LandstalkerGoal, LandstalkerOptions, ProgressiveArmors, TeleportTreeRequirements +from .Regions import * +from .Rules import * + + +class LandstalkerWeb(WebWorld): + theme = "grass" + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Landstalker Randomizer software on your computer.", + "English", + "landstalker_setup_en.md", + "landstalker_setup/en", + ["Dinopony"] + )] + + +class LandstalkerWorld(World): + """ + Landstalker: The Treasures of King Nole is a classic Action-RPG with an isometric view (also known as "2.5D"). + You play Nigel, a treasure hunter exploring the island of Mercator trying to find the legendary treasure. + Roam freely on the island, get stronger to beat dungeons and gather the required key items in order to reach the + hidden palace and claim the treasure. + """ + game = "Landstalker - The Treasures of King Nole" + options_dataclass = LandstalkerOptions + options: LandstalkerOptions + required_client_version = (0, 4, 4) + web = LandstalkerWeb() + + item_name_to_id = build_item_name_to_id_table() + location_name_to_id = build_location_name_to_id_table() + + cached_spheres: ClassVar[List[Set[Location]]] + + def __init__(self, multiworld, player): + super().__init__(multiworld, player) + self.regions_table: Dict[str, LandstalkerRegion] = {} + self.dark_dungeon_id = "None" + self.dark_region_ids = [] + self.teleport_tree_pairs = [] + self.jewel_items = [] + + def fill_slot_data(self) -> dict: + # Generate hints. + self.adjust_shop_prices() + hints = Hints.generate_random_hints(self) + hints["Lithograph"] = Hints.generate_lithograph_hint(self) + hints["Oracle Stone"] = f"It shows {self.dark_dungeon_id}\nenshrouded in darkness." + + # Put options, locations' contents and some additional data inside slot data + options = [ + "goal", "jewel_count", "progressive_armors", "use_record_book", "use_spell_book", "shop_prices_factor", + "combat_difficulty", "teleport_tree_requirements", "shuffle_trees", "ensure_ekeeke_in_shops", + "remove_gumi_boulder", "allow_whistle_usage_behind_trees", "handle_damage_boosting_in_logic", + "handle_enemy_jumping_in_logic", "handle_tree_cutting_glitch_in_logic", "hint_count", "death_link", + "revive_using_ekeeke", + ] + + slot_data = self.options.as_dict(*options) + slot_data["spawn_region"] = self.options.spawn_region.current_key + slot_data["seed"] = self.random.randint(0, 2 ** 32 - 1) + slot_data["dark_region"] = self.dark_dungeon_id + slot_data["hints"] = hints + slot_data["teleport_tree_pairs"] = [[pair[0]["name"], pair[1]["name"]] for pair in self.teleport_tree_pairs] + + # Type hinting for location. + location: LandstalkerLocation + slot_data["location_prices"] = { + location.name: location.price for location in self.multiworld.get_locations(self.player) if location.price} + + return slot_data + + def generate_early(self): + # Randomly pick a set of dark regions where Lantern is needed + darkenable_regions = get_darkenable_regions() + self.dark_dungeon_id = self.random.choice(list(darkenable_regions)) + self.dark_region_ids = darkenable_regions[self.dark_dungeon_id] + + def create_regions(self): + self.regions_table = Regions.create_regions(self) + Locations.create_locations(self.player, self.regions_table, self.location_name_to_id) + self.create_teleportation_trees() + + def create_item(self, name: str, classification_override: Optional[ItemClassification] = None) -> LandstalkerItem: + data = item_table[name] + classification = classification_override or data.classification + item = LandstalkerItem(name, classification, BASE_ITEM_ID + data.id, self.player) + item.price_in_shops = data.price_in_shops + return item + + def create_event(self, name: str) -> LandstalkerItem: + return LandstalkerItem(name, ItemClassification.progression, None, self.player) + + def get_filler_item_name(self) -> str: + return "EkeEke" + + def create_items(self): + item_pool: List[LandstalkerItem] = [] + for name, data in item_table.items(): + # If item is an armor and progressive armors are enabled, transform it into a progressive armor item + if self.options.progressive_armors and "Breast" in name: + name = "Progressive Armor" + item_pool += [self.create_item(name) for _ in range(data.quantity)] + + # If the appropriate setting is on, place one EkeEke in one shop in every town in the game + if self.options.ensure_ekeeke_in_shops: + shops_to_fill = [ + "Massan: Shop item #1", + "Gumi: Inn item #1", + "Ryuma: Inn item", + "Mercator: Shop item #1", + "Verla: Shop item #1", + "Destel: Inn item", + "Route to Lake Shrine: Greedly's shop item #1", + "Kazalt: Shop item #1" + ] + for location_name in shops_to_fill: + self.multiworld.get_location(location_name, self.player).place_locked_item(self.create_item("EkeEke")) + + # Add a fixed amount of progression Life Stock for a specific requirement (Fahl) + fahl_lifestock_req = 15 + item_pool += [self.create_item("Life Stock", ItemClassification.progression) for _ in range(fahl_lifestock_req)] + # Add a unique progression EkeEke for a specific requirement (Cutter) + item_pool.append(self.create_item("EkeEke", ItemClassification.progression)) + + # Add a variable amount of "useful" Life Stock to the pool, depending on the amount of starting Life Stock + # (i.e. on the starting location) + starting_lifestocks = self.get_starting_health() - 4 + lifestock_count = 80 - starting_lifestocks - fahl_lifestock_req + item_pool += [self.create_item("Life Stock") for _ in range(lifestock_count)] + + # Add jewels to the item pool depending on the number of jewels set in generation settings + self.jewel_items = [self.create_item(name) for name in self.get_jewel_names(self.options.jewel_count)] + item_pool += self.jewel_items + + # Add a pre-placed fake win condition item + self.multiworld.get_location("End", self.player).place_locked_item(self.create_event("King Nole's Treasure")) + + # Fill the rest of the item pool with EkeEke + remaining_items = len(self.multiworld.get_unfilled_locations(self.player)) - len(item_pool) + item_pool += [self.create_item(self.get_filler_item_name()) for _ in range(remaining_items)] + + self.multiworld.itempool += item_pool + + def create_teleportation_trees(self): + self.teleport_tree_pairs = load_teleport_trees() + + def pairwise(iterable): + """Yields pairs of elements from the given list -> [0,1], [2,3]...""" + a = iter(iterable) + return zip(a, a) + + # Shuffle teleport tree pairs if the matching setting is on + if self.options.shuffle_trees: + all_trees = [item for pair in self.teleport_tree_pairs for item in pair] + self.random.shuffle(all_trees) + self.teleport_tree_pairs = [[x, y] for x, y in pairwise(all_trees)] + + # If a specific setting is set, teleport trees are potentially active without visiting both sides. + # This means we need to add those as explorable paths for the generation algorithm. + teleport_trees_mode = self.options.teleport_tree_requirements.value + created_entrances = [] + if teleport_trees_mode in [TeleportTreeRequirements.option_none, TeleportTreeRequirements.option_clear_tibor]: + for pair in self.teleport_tree_pairs: + entrances = create_entrance(pair[0]["region"], pair[1]["region"], True, self.regions_table) + created_entrances += entrances + + # Teleport trees are open but require access to Tibor to work + if teleport_trees_mode == TeleportTreeRequirements.option_clear_tibor: + for entrance in created_entrances: + entrance.access_rule = make_path_requirement_lambda(self.player, [], [self.regions_table["tibor"]]) + + def set_rules(self): + Rules.create_rules(self) + + # In "Reach Kazalt" goal, player doesn't have access to Kazalt, King Nole's Labyrinth & King Nole's Palace. + # As a consequence, all locations inside those regions must be excluded, and the teleporter from + # King Nole's Cave to Kazalt must go to the end region instead. + if self.options.goal == LandstalkerGoal.option_reach_kazalt: + kazalt_tp = self.multiworld.get_entrance("king_nole_cave -> kazalt", self.player) + kazalt_tp.connected_region = self.regions_table["end"] + + excluded_regions = [ + "kazalt", + "king_nole_labyrinth_pre_door", + "king_nole_labyrinth_post_door", + "king_nole_labyrinth_exterior", + "king_nole_labyrinth_fall_from_exterior", + "king_nole_labyrinth_raft_entrance", + "king_nole_labyrinth_raft", + "king_nole_labyrinth_sacred_tree", + "king_nole_labyrinth_path_to_palace", + "king_nole_palace" + ] + + for location in self.multiworld.get_locations(self.player): + if location.parent_region.name in excluded_regions: + location.progress_type = LocationProgressType.EXCLUDED + + def get_starting_health(self): + spawn_id = self.options.spawn_region.current_key + if spawn_id == "destel": + return 20 + elif spawn_id == "verla": + return 16 + elif spawn_id in ["waterfall", "mercator", "greenmaze"]: + return 10 + else: + return 4 + + @classmethod + def stage_post_fill(cls, multiworld): + # Cache spheres for hint calculation after fill completes. + cls.cached_spheres = list(multiworld.get_spheres()) + + @classmethod + def stage_modify_multidata(cls, *_): + # Clean up all references in cached spheres after generation completes. + del cls.cached_spheres + + def adjust_shop_prices(self): + # Calculate prices for items in shops once all items have their final position + unknown_items_price = 250 + earlygame_price_factor = 1.0 + endgame_price_factor = 2.0 + factor_diff = endgame_price_factor - earlygame_price_factor + + global_price_factor = self.options.shop_prices_factor / 100.0 + + spheres = self.cached_spheres + sphere_count = len(spheres) + for sphere_id, sphere in enumerate(spheres): + location: LandstalkerLocation # after conditional, we guarantee it's this kind of location. + for location in sphere: + if location.player != self.player or location.type_string != "shop": + continue + + current_playthrough_progression = sphere_id / sphere_count + progression_price_factor = earlygame_price_factor + (current_playthrough_progression * factor_diff) + + price = location.item.price_in_shops \ + if location.item.game == "Landstalker - The Treasures of King Nole" else unknown_items_price + price *= progression_price_factor + price *= global_price_factor + price -= price % 5 + price = max(price, 5) + location.price = int(price) + + @staticmethod + def get_jewel_names(count: JewelCount): + if count < 6: + return ["Red Jewel", "Purple Jewel", "Green Jewel", "Blue Jewel", "Yellow Jewel"][:count] + + return ["Kazalt Jewel"] * count diff --git a/worlds/landstalker/data/hint_source.py b/worlds/landstalker/data/hint_source.py new file mode 100644 index 000000000000..4f22cac4bdd6 --- /dev/null +++ b/worlds/landstalker/data/hint_source.py @@ -0,0 +1,1989 @@ +HINT_SOURCES_JSON = [ + { + "description": "Lithograph", + "smallTextbox": True + }, + { + "description": "Oracle Stone", + "smallTextbox": True + }, + { + "description": "Mercator fortune teller", + "textIds": [ + 654 + ] + }, + { + "description": "King Nole's Cave sign", + "textIds": [ + 253 + ] + }, + { + "description": "Foxy (next to Ryuma's mayor house)", + "entity": { + "mapId": 611, + "position": { + "x": 47, + "y": 25, + "z": 3 + }, + "orientation": "sw" + }, + "nodeId": "ryuma" + }, + { + "description": "Foxy (behind trees in Gumi)", + "entity": { + "mapId": [602, 603], + "position": { + "x": 24, + "y": 35, + "z": 6 + }, + "orientation": "sw" + }, + "nodeId": "gumi" + }, + { + "description": "Foxy (next to Mercator gates)", + "entity": { + "mapId": 454, + "position": { + "x": 18, + "y": 46, + "z": 0 + }, + "orientation": "se" + }, + "nodeId": "route_gumi_ryuma" + }, + { + "description": "Foxy (near basin behind Mercator)", + "entity": { + "mapId": 636, + "position": { + "x": 18, + "y": 27, + "z": 1 + }, + "orientation": "nw" + }, + "nodeId": "mercator" + }, + { + "description": "Foxy (near cabin on Verla Shore)", + "entity": { + "mapId": 468, + "position": { + "x": 24, + "y": 45, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "verla_shore" + }, + { + "description": "Foxy (outside Verla Mines entrance)", + "entity": { + "mapId": 470, + "position": { + "x": 24, + "y": 29, + "z": 5 + }, + "orientation": "sw" + }, + "nodeId": "verla_shore" + }, + { + "description": "Foxy (room below Thieves Hideout summit)", + "entity": { + "mapId": 221, + "position": { + "x": 29, + "y": 19, + "z": 2 + }, + "orientation": "nw" + }, + "nodeId": "thieves_hideout_post_key" + }, + { + "description": "Foxy (near waterfall in Mountainous Area)", + "entity": { + "mapId": 485, + "position": { + "x": 42, + "y": 62, + "z": 2 + }, + "orientation": "nw", + "highPalette": True + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (in Mercator Castle left court)", + "entity": { + "mapId": 32, + "position": { + "x": 36, + "y": 38, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "mercator" + }, + { + "description": "Foxy (on Mercator inn balcony)", + "entity": { + "mapId": 632, + "position": { + "x": 19, + "y": 35, + "z": 4 + }, + "orientation": "se" + }, + "nodeId": "mercator" + }, + { + "description": "Foxy (on a beach between Ryuma and Mercator)", + "entity": { + "mapId": 450, + "position": { + "x": 18, + "y": 28, + "z": 0 + }, + "orientation": "nw" + }, + "nodeId": "route_gumi_ryuma" + }, + { + "description": "Foxy (atop Ryuma's lighthouse)", + "entity": { + "mapId": [628, 629], + "position": { + "x": 26, + "y": 21, + "z": 1 + }, + "orientation": "ne" + }, + "nodeId": "ryuma" + }, + { + "description": "Foxy (looking at dead man in Thieves Hideout)", + "entity": { + "mapId": 210, + "position": { + "x": 25, + "y": 20, + "z": 2 + }, + "orientation": "se" + }, + "nodeId": "thieves_hideout_pre_key" + }, + { + "description": "Foxy (contemplating water near goddess statue in Thieves Hideout)", + "entity": { + "mapId": [219, 220], + "position": { + "x": 36, + "y": 31, + "z": 2 + }, + "orientation": "se" + }, + "nodeId": "thieves_hideout_pre_key" + }, + { + "description": "Foxy (after timed trial in Thieves Hideout)", + "entity": { + "mapId": 196, + "position": { + "x": 49, + "y": 24, + "z": 10 + }, + "orientation": "sw" + }, + "nodeId": "thieves_hideout_post_key" + }, + { + "description": "Foxy (inside Mercator Castle armory tower)", + "entity": { + "mapId": 106, + "position": { + "x": 31, + "y": 30, + "z": 4 + }, + "orientation": "nw" + }, + "nodeId": "mercator" + }, + { + "description": "Foxy (near Mercator Castle kitchen)", + "entity": { + "mapId": 71, + "position": { + "x": 15, + "y": 19, + "z": 1 + }, + "orientation": "nw" + }, + "nodeId": "mercator" + }, + { + "description": "Foxy (in Mercator Castle library)", + "entity": { + "mapId": 73, + "position": { + "x": 18, + "y": 29, + "z": 0 + }, + "orientation": "nw" + }, + "nodeId": "mercator" + }, + { + "description": "Foxy (in Mercator Dungeon main room)", + "entity": { + "mapId": 38, + "position": { + "x": 24, + "y": 35, + "z": 3 + }, + "orientation": "se" + }, + "nodeId": "mercator_dungeon" + }, + { + "description": "Foxy (in hallway before tower in Mercator Dungeon)", + "entity": { + "mapId": 46, + "position": { + "x": 24, + "y": 13, + "z": 0 + }, + "orientation": "sw" + }, + "nodeId": "mercator_dungeon" + }, + { + "description": "Foxy (atop Mercator Dungeon tower)", + "entity": { + "mapId": 35, + "position": { + "x": 31, + "y": 31, + "z": 12 + }, + "orientation": "nw" + }, + "nodeId": "mercator_dungeon" + }, + { + "description": "Foxy (inside Mercator Crypt)", + "entity": { + "mapId": 647, + "position": { + "x": 30, + "y": 21, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "crypt" + }, + { + "description": "Foxy (on Verla beach)", + "entity": { + "mapId": 474, + "position": { + "x": 43, + "y": 30, + "z": 0 + }, + "orientation": "sw" + }, + "nodeId": "verla_shore" + }, + { + "description": "Foxy (spying on house in Verla)", + "entity": { + "mapId": [711, 712], + "position": { + "x": 48, + "y": 29, + "z": 5 + }, + "orientation": "nw" + }, + "nodeId": "verla" + }, + { + "description": "Foxy (on upper Verla shore, reachable from Dex exit)", + "entity": { + "mapId": 530, + "position": { + "x": 18, + "y": 29, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "verla_mines" + }, + { + "description": "Foxy (in Verla Mines jar staircase room)", + "entity": { + "mapId": 235, + "position": { + "x": 42, + "y": 22, + "z": 6 + }, + "orientation": "sw" + }, + "nodeId": "verla_mines" + }, + { + "description": "Foxy (in Verla Mines lizards and crates room)", + "entity": { + "mapId": 239, + "position": { + "x": 32, + "y": 31, + "z": 3, + "halfX": True, + "halfY": True + }, + "orientation": "ne" + }, + "nodeId": "verla_mines" + }, + { + "description": "Foxy (in Verla Mines lava room in Slasher sector)", + "entity": { + "mapId": 252, + "position": { + "x": 16, + "y": 13, + "z": 1, + "halfX": True, + "halfY": True + }, + "orientation": "sw" + }, + "nodeId": "verla_mines" + }, + { + "description": "Foxy (in Verla Mines room behind lava)", + "entity": { + "mapId": 265, + "position": { + "x": 13, + "y": 16, + "z": 0 + }, + "orientation": "se" + }, + "nodeId": "verla_mines" + }, + { + "description": "Foxy (in Verla Mines lava room in Marley sector)", + "entity": { + "mapId": 264, + "position": { + "x": 18, + "y": 19, + "z": 6, + "halfX": True, + "halfY": True + }, + "orientation": "sw" + }, + "nodeId": "verla_mines" + }, + { + "description": "Foxy (on small rocky ledge in elevator map near Kelketo shop)", + "entity": { + "mapId": 473, + "position": { + "x": 35, + "y": 25, + "z": 8 + }, + "orientation": "se" + }, + "nodeId": "route_verla_destel" + }, + { + "description": "Foxy (contemplating fast currents below Kelketo shop)", + "entity": { + "mapId": 481, + "position": { + "x": 40, + "y": 48, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "route_verla_destel" + }, + { + "description": "Foxy (in Destel)", + "entity": { + "mapId": 726, + "position": { + "x": 48, + "y": 55, + "z": 5 + }, + "orientation": "sw" + }, + "nodeId": "destel" + }, + { + "description": "Foxy (contemplating water near boatmaker house in route after Destel)", + "entity": { + "mapId": 489, + "position": { + "x": 23, + "y": 20, + "z": 1 + }, + "orientation": "ne" + }, + "nodeId": "route_after_destel" + }, + { + "description": "Foxy (looking at Lake Shrine from elevated viewpoint)", + "entity": { + "mapId": 525, + "position": { + "x": 53, + "y": 45, + "z": 5 + }, + "orientation": "ne" + }, + "nodeId": "route_after_destel" + }, + { + "description": "Foxy (on small floating block in Destel Well)", + "entity": { + "mapId": 275, + "position": { + "x": 27, + "y": 36, + "z": 5 + }, + "orientation": "nw" + }, + "nodeId": "destel_well" + }, + { + "description": "Foxy (in Destel Well watery hub room)", + "entity": { + "mapId": 283, + "position": { + "x": 34, + "y": 41, + "z": 2 + }, + "orientation": "nw" + }, + "nodeId": "destel_well" + }, + { + "description": "Foxy (in Destel Well watery room before boss)", + "entity": { + "mapId": 287, + "position": { + "x": 50, + "y": 46, + "z": 8, + "halfX": True, + "halfY": True + }, + "orientation": "nw" + }, + "nodeId": "destel_well" + }, + { + "description": "Foxy (at Destel Well exit on Lake Shrine side)", + "entity": { + "mapId": 545, + "position": { + "x": 58, + "y": 18, + "z": 0 + }, + "orientation": "sw" + }, + "nodeId": "route_lake_shrine" + }, + { + "description": "Foxy (at crossroads on route to Lake Shrine)", + "entity": { + "mapId": 515, + "position": { + "x": 30, + "y": 20, + "z": 4 + }, + "orientation": "nw" + }, + "nodeId": "route_lake_shrine" + }, + { + "description": "Foxy (on mountainous path to Lake Shrine)", + "entity": { + "mapId": 514, + "position": { + "x": 57, + "y": 24, + "z": 1 + }, + "orientation": "sw" + }, + "nodeId": "route_lake_shrine" + }, + { + "description": "Foxy (in volcano to Lake Shrine)", + "entity": { + "mapId": 522, + "position": { + "x": 50, + "y": 39, + "z": 6, + "halfX": True, + "halfY": True + }, + "orientation": "nw" + }, + "nodeId": "route_lake_shrine" + }, + { + "description": "Foxy (next to Lake Shrine door)", + "entity": { + "mapId": 524, + "position": { + "x": 24, + "y": 51, + "z": 2, + "halfX": True + }, + "orientation": "nw" + }, + "nodeId": "lake_shrine" + }, + { + "description": "Foxy (above Greedly's shop)", + "entity": { + "mapId": 503, + "position": { + "x": 23, + "y": 35, + "z": 8 + }, + "orientation": "se" + }, + "nodeId": "route_lake_shrine" + }, + { + "description": "Foxy (contemplating water near Greedly's teleport tree)", + "entity": { + "mapId": 501, + "position": { + "x": 30, + "y": 26, + "z": 5 + }, + "orientation": "sw" + }, + "nodeId": "route_lake_shrine" + }, + { + "description": "Foxy (in room after golem hops riddle in Lake Shrine)", + "entity": { + "mapId": 298, + "position": { + "x": 21, + "y": 19, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "lake_shrine" + }, + { + "description": "Foxy (in room next to green golem roundabout in Lake Shrine)", + "entity": { + "mapId": 293, + "position": { + "x": 19, + "y": 18, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "lake_shrine" + }, + { + "description": "Foxy (in Lake Shrine 'throne room')", + "entity": { + "mapId": 327, + "position": { + "x": 31, + "y": 31, + "z": 2 + }, + "orientation": "ne" + }, + "nodeId": "lake_shrine" + }, + { + "description": "Foxy (in room next to golden golems roundabout in Lake Shrine)", + "entity": { + "mapId": 353, + "position": { + "x": 31, + "y": 20, + "z": 4 + }, + "orientation": "sw" + }, + "nodeId": "lake_shrine" + }, + { + "description": "Foxy (in room near white golems roundabout in Lake Shrine)", + "entity": { + "mapId": 329, + "position": { + "x": 25, + "y": 25, + "z": 2, + "halfY": True + }, + "orientation": "nw" + }, + "nodeId": "lake_shrine" + }, + { + "description": "Foxy (next to Mir Tower)", + "entity": { + "mapId": 475, + "position": { + "x": 34, + "y": 17, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "mir_tower_sector" + }, + { + "description": "Foxy (on the way to Mir Tower)", + "entity": { + "mapId": 464, + "position": { + "x": 22, + "y": 40, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "mir_tower_sector" + }, + { + "description": "Foxy (near Twinkle Village)", + "entity": { + "mapId": 461, + "position": { + "x": 20, + "y": 21, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "mir_tower_sector" + }, + { + "description": "Foxy (inside Tibor)", + "entity": { + "mapId": 813, + "position": { + "x": 19, + "y": 32, + "z": 2 + }, + "orientation": "se" + }, + "nodeId": "tibor" + }, + { + "description": "Foxy (inside Tibor spikeballs room)", + "entity": { + "mapId": 810, + "position": { + "x": 21, + "y": 33, + "z": 2, + "halfX": True, + "halfY": True + }, + "orientation": "ne" + }, + "nodeId": "tibor" + }, + { + "description": "Foxy (near Kado's house)", + "entity": { + "mapId": 430, + "position": { + "x": 24, + "y": 27, + "z": 11 + }, + "orientation": "se" + }, + "nodeId": "route_gumi_ryuma" + }, + { + "description": "Foxy (in Gumi boulder map)", + "entity": { + "mapId": 449, + "position": { + "x": 48, + "y": 20, + "z": 1, + "halfX": True + }, + "orientation": "sw" + }, + "nodeId": "route_gumi_ryuma" + }, + { + "description": "Foxy (at Waterfall Shrine crossroads)", + "entity": { + "mapId": 425, + "position": { + "x": 22, + "y": 56, + "z": 0, + "halfX": True + }, + "orientation": "sw" + }, + "nodeId": "route_massan_gumi" + }, + { + "description": "Foxy (in upstairs room inside Waterfall Shrine)", + "entity": { + "mapId": 182, + "position": { + "x": 29, + "y": 19, + "z": 4 + }, + "orientation": "nw" + }, + "nodeId": "waterfall_shrine" + }, + { + "description": "Foxy (inside Waterfall Shrine pit)", + "entity": { + "mapId": 174, + "position": { + "x": 32, + "y": 29, + "z": 1 + }, + "orientation": "sw" + }, + "nodeId": "waterfall_shrine" + }, + { + "description": "Foxy (in Massan)", + "entity": { + "mapId": 592, + "position": { + "x": 24, + "y": 46, + "z": 0, + "halfY": True + }, + "orientation": "se" + }, + "nodeId": "massan" + }, + { + "description": "Foxy (in room at the bottom of ladders in Massan Cave)", + "entity": { + "mapId": 805, + "position": { + "x": 34, + "y": 30, + "z": 2, + "halfY": True + }, + "orientation": "se" + }, + "nodeId": "massan_cave" + }, + { + "description": "Foxy (in treasure room of Massan Cave)", + "entity": { + "mapId": 807, + "position": { + "x": 28, + "y": 22, + "z": 1 + }, + "orientation": "sw" + }, + "nodeId": "massan_cave" + }, + { + "description": "Foxy (bathing in the swamp next to Swamp Shrine entrance)", + "entity": { + "mapId": 433, + "position": { + "x": 39, + "y": 20, + "z": 0 + }, + "orientation": "sw" + }, + "nodeId": "massan_cave" + }, + { + "description": "Foxy (in side room of Swamp Shrine accessible without Idol Stone)", + "entity": { + "mapId": 10, + "position": { + "x": 25, + "y": 27, + "z": 2, + "halfX": True + }, + "orientation": "ne" + }, + "nodeId": "route_massan_gumi" + }, + { + "description": "Foxy (in wooden room with falling EkeEke chest in Swamp Shrine)", + "entity": { + "mapId": 7, + "position": { + "x": 29, + "y": 25, + "z": 1, + "halfY": True + }, + "orientation": "nw" + }, + "nodeId": "swamp_shrine" + }, + { + "description": "Foxy (in Swamp Shrine carpet room)", + "entity": { + "mapId": 2, + "position": { + "x": 19, + "y": 33, + "z": 4 + }, + "orientation": "se" + }, + "nodeId": "swamp_shrine" + }, + { + "description": "Foxy (in Swamp Shrine spikeball storage room)", + "entity": { + "mapId": 16, + "position": { + "x": 25, + "y": 24, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "swamp_shrine" + }, + { + "description": "Foxy (in Swamp Shrine spiked floor room)", + "entity": { + "mapId": 21, + "position": { + "x": 27, + "y": 17, + "z": 4 + }, + "orientation": "sw" + }, + "nodeId": "swamp_shrine" + }, + { + "description": "Foxy (in Mercator Castle backdoor court)", + "entity": { + "mapId": 639, + "position": { + "x": 23, + "y": 15, + "z": 0 + }, + "orientation": "sw" + }, + "nodeId": "mercator" + }, + { + "description": "Foxy (on Greenmaze / Mountainous Area crossroad)", + "entity": { + "mapId": 460, + "position": { + "x": 16, + "y": 27, + "z": 4 + }, + "orientation": "se" + }, + "nodeId": "greenmaze_pre_whistle" + }, + { + "description": "Foxy (below Mountainous Area bridge)", + "entity": { + "mapId": 486, + "position": { + "x": 52, + "y": 45, + "z": 5 + }, + "orientation": "se" + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (in Mountainous Area isolated cave)", + "entity": { + "mapId": 553, + "position": { + "x": 23, + "y": 21, + "z": 3 + }, + "orientation": "ne" + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (in access to Zak arena inside Mountainous Area)", + "entity": { + "mapId": 487, + "position": { + "x": 44, + "y": 51, + "z": 3 + }, + "orientation": "se" + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (in Zak arena inside Mountainous Area)", + "entity": { + "mapId": 492, + "position": { + "x": 27, + "y": 55, + "z": 9 + }, + "orientation": "se" + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (in empty secret room inside Mountainous Area cave)", + "entity": { + "mapId": 552, + "position": { + "x": 24, + "y": 27, + "z": 0, + "halfX": True + }, + "orientation": "sw" + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (in empty visible room inside Mountainous Area cave)", + "entity": { + "mapId": 547, + "position": { + "x": 23, + "y": 23, + "z": 0, + "halfY": True + }, + "orientation": "se" + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (in waterfall entrance of Mountainous Area cave)", + "entity": { + "mapId": 549, + "position": { + "x": 27, + "y": 40, + "z": 0 + }, + "orientation": "se" + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (on Mir Tower sector crossroads)", + "entity": { + "mapId": 458, + "position": { + "x": 21, + "y": 21, + "z": 1 + }, + "orientation": "se", + "highPalette": True + }, + "nodeId": "mir_tower_sector" + }, + { + "description": "Foxy (near Mountainous Area teleport tree)", + "entity": { + "mapId": 484, + "position": { + "x": 38, + "y": 57, + "z": 0 + }, + "orientation": "sw", + "highPalette": True + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (on route to Mountainous Area, in rocky arch map)", + "entity": { + "mapId": 500, + "position": { + "x": 19, + "y": 19, + "z": 7 + }, + "orientation": "sw", + "highPalette": True + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (on route to Mountainous Area, in L-shaped turn map)", + "entity": { + "mapId": 540, + "position": { + "x": 16, + "y": 23, + "z": 3 + }, + "orientation": "se", + "halfY": True, + "highPalette": True + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (in map next to Mountainous Area goddess statue)", + "entity": { + "mapId": 518, + "position": { + "x": 38, + "y": 33, + "z": 12 + }, + "orientation": "sw", + "highPalette": True + }, + "nodeId": "mountainous_area" + }, + { + "description": "Foxy (in King Nole's Cave isolated chest room)", + "entity": { + "mapId": 156, + "position": { + "x": 21, + "y": 27, + "z": 0, + "halfX": True + }, + "orientation": "ne" + }, + "nodeId": "king_nole_cave" + }, + { + "description": "Foxy (in King Nole's Cave crate stairway room)", + "entity": { + "mapId": 158, + "position": { + "x": 29, + "y": 26, + "z": 6 + }, + "orientation": "sw", + "highPalette": True + }, + "nodeId": "king_nole_cave" + }, + { + "description": "Foxy (in room before boulder hallway inside King Nole's Cave)", + "entity": { + "mapId": 147, + "position": { + "x": 26, + "y": 23, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "king_nole_cave" + }, + { + "description": "Foxy (in empty isolated room inside King Nole's Cave)", + "entity": { + "mapId": 162, + "position": { + "x": 26, + "y": 17, + "z": 0, + "halfX": True + }, + "orientation": "sw" + }, + "nodeId": "king_nole_cave" + }, + { + "description": "Foxy (looking at the waterfall in King Nole's Cave)", + "entity": { + "mapId": 164, + "position": { + "x": 22, + "y": 48, + "z": 1 + }, + "orientation": "sw", + "highPalette": True + }, + "nodeId": "king_nole_cave" + }, + { + "description": "Foxy (in King Nole's Cave teleporter to Kazalt)", + "entity": { + "mapId": 170, + "position": { + "x": 22, + "y": 27, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "king_nole_cave" + }, + { + "description": "Foxy (in access to Kazalt)", + "entity": { + "mapId": 739, + "position": { + "x": 17, + "y": 28, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "kazalt" + }, + { + "description": "Foxy (on Kazalt bridge)", + "entity": { + "mapId": 737, + "position": { + "x": 46, + "y": 34, + "z": 7 + }, + "orientation": "se" + }, + "nodeId": "kazalt" + }, + { + "description": "Foxy (in Mir Tower 0F isolated chest room)", + "entity": { + "mapId": 757, + "position": { + "x": 19, + "y": 24, + "z": 0 + }, + "orientation": "se" + }, + "nodeId": "mir_tower_pre_garlic" + }, + { + "description": "Foxy (in Mir Tower activatable bridge room)", + "entity": { + "mapId": [752, 753], + "position": { + "x": 29, + "y": 34, + "z": 3, + "halfX": True + }, + "orientation": "sw" + }, + "nodeId": "mir_tower_pre_garlic" + }, + { + "description": "Foxy (in Garlic trial room inside Mir Tower)", + "entity": { + "mapId": 750, + "position": { + "x": 22, + "y": 21, + "z": 4 + }, + "orientation": "sw" + }, + "nodeId": "mir_tower_pre_garlic" + }, + { + "description": "Foxy (in Mir Tower library)", + "entity": { + "mapId": 759, + "position": { + "x": 38, + "y": 29, + "z": 4 + }, + "orientation": "ne" + }, + "nodeId": "mir_tower_post_garlic" + }, + { + "description": "Foxy (in Mir Tower priest room)", + "entity": { + "mapId": 775, + "position": { + "x": 23, + "y": 22, + "z": 1, + "halfX": True + }, + "orientation": "sw" + }, + "nodeId": "mir_tower_post_garlic" + }, + { + "description": "Foxy (right after making Miro flee with Garlic in Mir Tower)", + "entity": { + "mapId": 758, + "position": { + "x": 14, + "y": 34, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "mir_tower_post_garlic" + }, + { + "description": "Foxy (in falling spikeballs room inside Mir Tower)", + "entity": { + "mapId": 761, + "position": { + "x": 14, + "y": 24, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "mir_tower_post_garlic" + }, + { + "description": "Foxy (in first room of Mir Tower teleporter maze)", + "entity": { + "mapId": 767, + "position": { + "x": 18, + "y": 18, + "z": 2 + }, + "orientation": "se" + }, + "nodeId": "mir_tower_post_garlic" + }, + { + "description": "Foxy (in small spikeballs room of Mir Tower teleporter maze)", + "entity": { + "mapId": 771, + "position": { + "x": 18, + "y": 18, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "mir_tower_post_garlic" + }, + { + "description": "Foxy (in wooden elevators room after Mir Tower teleporter maze)", + "entity": { + "mapId": 779, + "position": { + "x": 32, + "y": 20, + "z": 7, + "halfY": True + }, + "orientation": "nw" + }, + "nodeId": "mir_tower_post_garlic" + }, + { + "description": "Foxy (in room before Mir Tower boss room)", + "entity": { + "mapId": 783, + "position": { + "x": 32, + "y": 19, + "z": 2 + }, + "orientation": "se" + }, + "nodeId": "mir_tower_post_garlic" + }, + { + "description": "Foxy (in Mir Tower treasure room)", + "entity": { + "mapId": 781, + "position": { + "x": 53, + "y": 26, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "mir_tower_post_garlic" + }, + { + "description": "Foxy (next to Waterfall Shrine entrance)", + "entity": { + "mapId": 426, + "position": { + "x": 46, + "y": 31, + "z": 0, + "halfX": True, + "halfY": True + }, + "orientation": "sw" + }, + "nodeId": "route_massan_gumi" + }, + { + "description": "Foxy (looking at river next to Massan teleport tree)", + "entity": { + "mapId": 424, + "position": { + "x": 44, + "y": 35, + "z": 0 + }, + "orientation": "nw" + }, + "nodeId": "route_massan_gumi" + }, + { + "description": "Foxy (looking at bush at Swamp Shrine crossroads)", + "entity": { + "mapId": 440, + "position": { + "x": 25, + "y": 42, + "z": 4 + }, + "orientation": "nw", + "highPalette": True + }, + "nodeId": "route_massan_gumi" + }, + { + "description": "Foxy (at Helga's Hut crossroads)", + "entity": { + "mapId": 447, + "position": { + "x": 24, + "y": 17, + "z": 1 + }, + "orientation": "se", + "highPalette": True + }, + "nodeId": "route_gumi_ryuma" + }, + { + "description": "Foxy (near Helga's Hut)", + "entity": { + "mapId": 444, + "position": { + "x": 25, + "y": 26, + "z": 7 + }, + "orientation": "sw" + }, + "nodeId": "route_gumi_ryuma" + }, + { + "description": "Foxy (in reapers room at Greenmaze entrance)", + "entity": { + "mapId": 571, + "position": { + "x": 31, + "y": 20, + "z": 6 + }, + "orientation": "nw", + "highPalette": True + }, + "nodeId": "greenmaze_pre_whistle" + }, + { + "description": "Foxy (near Greenmaze swamp)", + "entity": { + "mapId": 566, + "position": { + "x": 53, + "y": 51, + "z": 1 + }, + "orientation": "ne" + }, + "nodeId": "greenmaze_pre_whistle" + }, + { + "description": "Foxy (spying on Cutter in Greenmaze)", + "entity": { + "mapId": 560, + "position": { + "x": 31, + "y": 52, + "z": 9 + }, + "orientation": "nw" + }, + "nodeId": "greenmaze_pre_whistle" + }, + { + "description": "Foxy (in sector with red orcs making an elevator appear in Greenmaze)", + "entity": { + "mapId": 565, + "position": { + "x": 50, + "y": 30, + "z": 1 + }, + "orientation": "se" + }, + "nodeId": "greenmaze_pre_whistle" + }, + { + "description": "Foxy (in center of Greenmaze)", + "entity": { + "mapId": 576, + "position": { + "x": 32, + "y": 38, + "z": 5, + "halfY": True + }, + "orientation": "se" + }, + "nodeId": "greenmaze_pre_whistle" + }, + { + "description": "Foxy (in waterfall sector of Greenmaze)", + "entity": { + "mapId": 568, + "position": { + "x": 29, + "y": 41, + "z": 7, + "halfX": True + }, + "orientation": "ne", + "highPalette": True + }, + "nodeId": "greenmaze_pre_whistle" + }, + { + "description": "Foxy (in ropes sector of Greenmaze)", + "entity": { + "mapId": 567, + "position": { + "x": 38, + "y": 28, + "z": 0 + }, + "orientation": "se" + }, + "nodeId": "greenmaze_pre_whistle" + }, + { + "description": "Foxy (in Sun Stone sector of Greenmaze)", + "entity": { + "mapId": 564, + "position": { + "x": 30, + "y": 35, + "z": 1 + }, + "orientation": "sw" + }, + "nodeId": "greenmaze_pre_whistle" + }, + { + "description": "Foxy (in first chest map of Greenmaze after cutting trees)", + "entity": { + "mapId": 570, + "position": { + "x": 26, + "y": 15, + "z": 1 + }, + "orientation": "sw" + }, + "nodeId": "greenmaze_post_whistle" + }, + { + "description": "Foxy (near shortcut cavern entrance in Greenmaze after cutting trees)", + "entity": { + "mapId": 569, + "position": { + "x": 20, + "y": 24, + "z": 6, + "halfY": True + }, + "orientation": "se" + }, + "nodeId": "greenmaze_post_whistle" + }, + { + "description": "Foxy (in room next to spiked floor and keydoor room in King Nole's Labyrinth)", + "entity": { + "mapId": 380, + "position": { + "x": 17, + "y": 18, + "z": 0 + }, + "orientation": "se" + }, + "nodeId": "king_nole_labyrinth_pre_door" + }, + { + "description": "Foxy (in ice shortcut room in King Nole's Labyrinth)", + "entity": { + "mapId": 390, + "position": { + "x": 19, + "y": 41, + "z": 2 + }, + "orientation": "se" + }, + "nodeId": "king_nole_labyrinth_pre_door" + }, + { + "description": "Foxy (in exterior room of King Nole's Labyrinth)", + "entity": { + "mapId": 362, + "position": { + "x": 35, + "y": 21, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "king_nole_labyrinth_pre_door" + }, + { + "description": "Foxy (in room above Iron Boots in King Nole's Labyrinth)", + "entity": { + "mapId": 373, + "position": { + "x": 26, + "y": 30, + "z": 2 + }, + "orientation": "se" + }, + "nodeId": "king_nole_labyrinth_post_door" + }, + { + "description": "Foxy (next to raft starting point in King Nole's Labyrinth)", + "entity": { + "mapId": 406, + "position": { + "x": 46, + "y": 40, + "z": 7 + }, + "orientation": "nw", + "highPalette": True + }, + "nodeId": "king_nole_labyrinth_raft_entrance" + }, + { + "description": "Foxy (in fast boulder room in King Nole's Labyrinth)", + "entity": { + "mapId": 382, + "position": { + "x": 30, + "y": 30, + "z": 7, + "halfX": True + }, + "orientation": "ne" + }, + "nodeId": "king_nole_labyrinth_post_door" + }, + { + "description": "Foxy (in first maze room inside King Nole's Labyrinth)", + "entity": { + "mapId": 367, + "position": { + "x": 43, + "y": 38, + "z": 1 + }, + "orientation": "sw" + }, + "nodeId": "king_nole_labyrinth_post_door" + }, + { + "description": "Foxy (in lava sector of King Nole's Labyrinth)", + "entity": { + "mapId": 399, + "position": { + "x": 23, + "y": 19, + "z": 2, + "halfY": True + }, + "orientation": "se" + }, + "nodeId": "king_nole_labyrinth_post_door" + }, + { + "description": "Foxy (in hands room inside King Nole's Labyrinth)", + "entity": { + "mapId": 418, + "position": { + "x": 41, + "y": 31, + "z": 7 + }, + "orientation": "sw" + }, + "nodeId": "king_nole_labyrinth_post_door" + }, + { + "description": "Foxy (next to King Nole's Palace entrance)", + "entity": { + "mapId": 422, + "position": { + "x": 27, + "y": 25, + "z": 2 + }, + "orientation": "ne" + }, + "nodeId": "king_nole_labyrinth_path_to_palace" + }, + { + "description": "Foxy (in King Nole's Palace entrance room)", + "entity": { + "mapId": 122, + "position": { + "x": 30, + "y": 35, + "z": 8 + }, + "orientation": "ne" + }, + "nodeId": "king_nole_palace" + }, + { + "description": "Foxy (in King Nole's Palace jar and moving platforms room)", + "entity": { + "mapId": 126, + "position": { + "x": 27, + "y": 37, + "z": 6 + }, + "orientation": "se" + }, + "nodeId": "king_nole_palace" + }, + { + "description": "Foxy (in King Nole's Palace last chest room)", + "entity": { + "mapId": 125, + "position": { + "x": 25, + "y": 39, + "z": 2 + }, + "orientation": "ne" + }, + "nodeId": "king_nole_palace" + }, + { + "description": "Foxy (in Mercator casino)", + "entity": { + "mapId": 663, + "position": { + "x": 16, + "y": 58, + "z": 0, + "halfX": True, + "halfY": True + }, + "orientation": "ne" + }, + "nodeId": "mercator_casino" + }, + { + "description": "Foxy (in Helga's hut basement)", + "entity": { + "mapId": 479, + "position": { + "x": 20, + "y": 33, + "z": 0, + "halfX": True + }, + "orientation": "sw" + }, + "nodeId": "helga_hut" + }, + { + "description": "Foxy (in Helga's hut dungeon deepest room)", + "entity": { + "mapId": 802, + "position": { + "x": 28, + "y": 19, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "helga_hut" + }, + { + "description": "Foxy (in Helga's hut dungeon topmost room)", + "entity": { + "mapId": 786, + "position": { + "x": 25, + "y": 23, + "z": 2, + "halfY": True + }, + "orientation": "se" + }, + "nodeId": "helga_hut" + }, + { + "description": "Foxy (in Swamp Shrine right aisle room)", + "entity": { + "mapId": 1, + "position": { + "x": 34, + "y": 20, + "z": 2 + }, + "orientation": "se", + "highPalette": True + }, + "nodeId": "swamp_shrine" + }, + { + "description": "Foxy (upstairs in Swamp Shrine main hall)", + "entity": { + "mapId": [5, 15], + "position": { + "x": 45, + "y": 24, + "z": 8, + "halfY": True + }, + "orientation": "nw" + }, + "nodeId": "swamp_shrine" + }, + { + "description": "Foxy (in room before boss inside Swamp Shrine)", + "entity": { + "mapId": 30, + "position": { + "x": 19, + "y": 25, + "z": 2, + "halfY": True + }, + "orientation": "se" + }, + "nodeId": "swamp_shrine" + }, + { + "description": "Foxy (in Thieves Hideout entrance room)", + "entity": { + "mapId": [185, 186], + "position": { + "x": 40, + "y": 35, + "z": 2 + }, + "orientation": "se", + "highPalette": True + }, + "nodeId": "thieves_hideout_pre_key" + }, + { + "description": "Foxy (in Thieves Hideout room with hidden door behind waterfall)", + "entity": { + "mapId": [192, 193], + "position": { + "x": 30, + "y": 34, + "z": 1 + }, + "orientation": "nw" + }, + "nodeId": "thieves_hideout_pre_key" + }, + { + "description": "Foxy (in Thieves Hideout double chest room before goddess statue)", + "entity": { + "mapId": 215, + "position": { + "x": 17, + "y": 17, + "z": 0 + }, + "orientation": "sw" + }, + "nodeId": "thieves_hideout_pre_key" + }, + { + "description": "Foxy (in hub room after Thieves Hideout keydoor)", + "entity": { + "mapId": 199, + "position": { + "x": 24, + "y": 52, + "z": 2 + }, + "orientation": "sw" + }, + "nodeId": "thieves_hideout_post_key" + }, + { + "description": "Foxy (in reward room after Thieves Hideout moving balls riddle)", + "entity": { + "mapId": 205, + "position": { + "x": 32, + "y": 24, + "z": 0 + }, + "orientation": "sw" + }, + "nodeId": "thieves_hideout_post_key" + }, + { + "description": "Foxy (in Lake Shrine main hallway)", + "entity": { + "mapId": 302, + "position": { + "x": 20, + "y": 19, + "z": 0 + }, + "orientation": "sw" + }, + "nodeId": "lake_shrine" + }, + { + "description": "Foxy (in triple chest room in Slasher sector of Verla Mines)", + "entity": { + "mapId": 256, + "position": { + "x": 23, + "y": 23, + "z": 0 + }, + "orientation": "sw" + }, + "nodeId": "verla_mines" + }, + { + "description": "Foxy (near teleport tree after Destel)", + "entity": { + "mapId": 488, + "position": { + "x": 28, + "y": 53, + "z": 0 + }, + "orientation": "se" + }, + "nodeId": "route_after_destel" + }, + { + "description": "Foxy (in lower half of mimics room in King Nole's Labyrinth)", + "entity": { + "mapId": 383, + "position": { + "x": 26, + "y": 26, + "z": 2 + }, + "orientation": "nw" + }, + "nodeId": "king_nole_labyrinth_pre_door" + } +] diff --git a/worlds/landstalker/data/item_source.py b/worlds/landstalker/data/item_source.py new file mode 100644 index 000000000000..e0a2d701f4bf --- /dev/null +++ b/worlds/landstalker/data/item_source.py @@ -0,0 +1,2017 @@ +ITEM_SOURCES_JSON = [ + { + "name": "Swamp Shrine (0F): chest in room to the right", + "type": "chest", + "nodeId": "swamp_shrine", + "chestId": 0 + }, + { + "name": "Swamp Shrine (0F): chest in carpet room", + "type": "chest", + "nodeId": "swamp_shrine", + "chestId": 1 + }, + { + "name": "Swamp Shrine (0F): chest in left hallway (accessed by falling from upstairs)", + "type": "chest", + "nodeId": "swamp_shrine", + "chestId": 2 + }, + { + "name": "Swamp Shrine (0F): falling chest after beating orc", + "type": "chest", + "nodeId": "swamp_shrine", + "chestId": 3 + }, + { + "name": "Swamp Shrine (0F): chest in room visible from second entrance", + "type": "chest", + "nodeId": "swamp_shrine", + "chestId": 4 + }, + { + "name": "Swamp Shrine (1F): lower chest in wooden bridges room", + "type": "chest", + "nodeId": "swamp_shrine", + "chestId": 5 + }, + { + "name": "Swamp Shrine (2F): upper chest in wooden bridges room", + "type": "chest", + "nodeId": "swamp_shrine", + "chestId": 6 + }, + { + "name": "Swamp Shrine (2F): chest on spiked floor room balcony", + "type": "chest", + "nodeId": "swamp_shrine", + "chestId": 7 + }, + { + "name": "Swamp Shrine (3F): chest in boss arena", + "type": "chest", + "nodeId": "swamp_shrine", + "chestId": 8 + }, + { + "name": "Mercator Dungeon (-1F): chest on elevated path near entrance", + "type": "chest", + "nodeId": "mercator_dungeon", + "hints": [ + "hidden in the depths of Mercator" + ], + "chestId": 9 + }, + { + "name": "Mercator Dungeon (-1F): chest in Moralis's cell", + "type": "chest", + "nodeId": "mercator_dungeon", + "hints": [ + "hidden in the depths of Mercator" + ], + "chestId": 10 + }, + { + "name": "Mercator Dungeon (-1F): left chest in undeground double chest room", + "type": "chest", + "nodeId": "mercator_dungeon", + "hints": [ + "hidden in the depths of Mercator" + ], + "chestId": 11 + }, + { + "name": "Mercator Dungeon (-1F): right chest in undeground double chest room", + "type": "chest", + "nodeId": "mercator_dungeon", + "hints": [ + "hidden in the depths of Mercator" + ], + "chestId": 12 + }, + { + "name": "Mercator: castle kitchen chest", + "type": "chest", + "nodeId": "mercator", + "chestId": 13 + }, + { + "name": "Mercator: chest in special shop backroom", + "type": "chest", + "nodeId": "mercator", + "chestId": 14 + }, + { + "name": "Mercator Dungeon (1F): left chest in tower double chest room", + "type": "chest", + "nodeId": "mercator_dungeon", + "hints": [ + "inside a tower" + ], + "chestId": 15 + }, + { + "name": "Mercator Dungeon (1F): right chest in tower double chest room", + "type": "chest", + "nodeId": "mercator_dungeon", + "hints": [ + "inside a tower" + ], + "chestId": 16 + }, + { + "name": "Mercator: chest in castle tower (ladder revealed by slashing armor)", + "type": "chest", + "nodeId": "mercator", + "hints": [ + "inside a tower" + ], + "chestId": 17 + }, + { + "name": "Mercator Dungeon (4F): chest in topmost tower room", + "type": "chest", + "nodeId": "mercator_dungeon", + "hints": [ + "inside a tower" + ], + "chestId": 18 + }, + { + "name": "King Nole's Palace: chest at entrance", + "type": "chest", + "nodeId": "king_nole_palace", + "chestId": 19 + }, + { + "name": "King Nole's Palace: chest along central pit", + "type": "chest", + "nodeId": "king_nole_palace", + "chestId": 20 + }, + { + "name": "King Nole's Palace: chest in floating button room", + "type": "chest", + "nodeId": "king_nole_palace", + "chestId": 21 + }, + { + "name": "King Nole's Cave: chest in second room", + "type": "chest", + "nodeId": "king_nole_cave", + "chestId": 22 + }, + { + "name": "King Nole's Cave: first chest in third room", + "type": "chest", + "nodeId": "king_nole_cave", + "chestId": 24 + }, + { + "name": "King Nole's Cave: second chest in third room", + "type": "chest", + "nodeId": "king_nole_cave", + "chestId": 25 + }, + { + "name": "King Nole's Cave: chest in isolated room", + "type": "chest", + "nodeId": "king_nole_cave", + "chestId": 28 + }, + { + "name": "King Nole's Cave: chest in crate room", + "type": "chest", + "nodeId": "king_nole_cave", + "chestId": 29 + }, + { + "name": "King Nole's Cave: boulder chase hallway chest", + "type": "chest", + "nodeId": "king_nole_cave", + "chestId": 31 + }, + { + "name": "Waterfall Shrine: chest under entrance hallway", + "type": "chest", + "nodeId": "waterfall_shrine", + "chestId": 33 + }, + { + "name": "Waterfall Shrine: chest near Prospero", + "type": "chest", + "nodeId": "waterfall_shrine", + "chestId": 34 + }, + { + "name": "Waterfall Shrine: chest on right branch of biggest room", + "type": "chest", + "nodeId": "waterfall_shrine", + "chestId": 35 + }, + { + "name": "Waterfall Shrine: upstairs chest", + "type": "chest", + "nodeId": "waterfall_shrine", + "chestId": 36 + }, + { + "name": "Thieves Hideout: chest under water in entrance room", + "type": "chest", + "nodeId": "thieves_hideout_pre_key", + "chestId": 38 + }, + { + "name": "Thieves Hideout (back): right chest after teal knight mini-boss", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 41 + }, + { + "name": "Thieves Hideout (back): left chest after teal knight mini-boss", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 42 + }, + { + "name": "Thieves Hideout: left chest in Pockets cell", + "type": "chest", + "nodeId": "thieves_hideout_pre_key", + "chestId": 43 + }, + { + "name": "Thieves Hideout: right chest in Pockets cell", + "type": "chest", + "nodeId": "thieves_hideout_pre_key", + "chestId": 44 + }, + { + "name": "Thieves Hideout (back): second chest in hallway after quick climb trial", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 45 + }, + { + "name": "Thieves Hideout (back): first chest in hallway after quick climb trial", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 46 + }, + { + "name": "Thieves Hideout (back): chest in moving platforms room", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 47 + }, + { + "name": "Thieves Hideout (back): chest in falling platforms room", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 48 + }, + { + "name": "Thieves Hideout (back): reward chest after moving balls room", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 49 + }, + { + "name": "Thieves Hideout: rolling boulder chest near entrance", + "type": "chest", + "nodeId": "thieves_hideout_pre_key", + "chestId": 50 + }, + { + "name": "Thieves Hideout: left chest in room on the way to goddess statue", + "type": "chest", + "nodeId": "thieves_hideout_pre_key", + "chestId": 52 + }, + { + "name": "Thieves Hideout: right chest in room on the way to goddess statue", + "type": "chest", + "nodeId": "thieves_hideout_pre_key", + "chestId": 53 + }, + { + "name": "Thieves Hideout (back): left chest in room before boss", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 54 + }, + { + "name": "Thieves Hideout (back): right chest in room before boss", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 55 + }, + { + "name": "Thieves Hideout (back): chest #1 in boss reward room", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 56 + }, + { + "name": "Thieves Hideout (back): chest #2 in boss reward room", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 57 + }, + { + "name": "Thieves Hideout (back): chest #3 in boss reward room", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 58 + }, + { + "name": "Thieves Hideout (back): chest #4 in boss reward room", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 59 + }, + { + "name": "Thieves Hideout (back): chest #5 in boss reward room", + "type": "chest", + "nodeId": "thieves_hideout_post_key", + "chestId": 60 + }, + { + "name": "Verla Mines: right chest in double chest room near entrance", + "type": "chest", + "nodeId": "verla_mines", + "chestId": 66 + }, + { + "name": "Verla Mines: left chest in double chest room near entrance", + "type": "chest", + "nodeId": "verla_mines", + "chestId": 67 + }, + { + "name": "Verla Mines: chest on jar staircase room balcony", + "type": "chest", + "nodeId": "verla_mines", + "chestId": 68 + }, + { + "name": "Verla Mines: Dex reward chest", + "type": "chest", + "nodeId": "verla_mines", + "chestId": 69 + }, + { + "name": "Verla Mines: Slasher reward chest", + "type": "chest", + "nodeId": "verla_mines", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 70 + }, + { + "name": "Verla Mines: left chest in 3-chests room near Slasher", + "type": "chest", + "nodeId": "verla_mines", + "chestId": 71 + }, + { + "name": "Verla Mines: middle chest in 3-chests room near Slasher", + "type": "chest", + "nodeId": "verla_mines", + "chestId": 72 + }, + { + "name": "Verla Mines: right chest in 3-chests room near Slasher", + "type": "chest", + "nodeId": "verla_mines", + "chestId": 73 + }, + { + "name": "Verla Mines: right chest in button room near elevator shaft leading to Marley", + "type": "chest", + "nodeId": "verla_mines", + "chestId": 74 + }, + { + "name": "Verla Mines: left chest in button room near elevator shaft leading to Marley", + "type": "chest", + "nodeId": "verla_mines", + "chestId": 75 + }, + { + "name": "Verla Mines: chest in hidden room accessed by walking on lava", + "type": "chest", + "nodeId": "verla_mines_behind_lava", + "hints": [ + "in a very hot place" + ], + "chestId": 76 + }, + { + "name": "Destel Well (0F): 4 crates puzzle room chest", + "type": "chest", + "nodeId": "destel_well", + "chestId": 77 + }, + { + "name": "Destel Well (1F): chest on small stairs", + "type": "chest", + "nodeId": "destel_well", + "chestId": 78 + }, + { + "name": "Destel Well (1F): chest on narrow floating ground", + "type": "chest", + "nodeId": "destel_well", + "chestId": 79 + }, + { + "name": "Destel Well (1F): chest in spiky hallway", + "type": "chest", + "nodeId": "destel_well", + "chestId": 80 + }, + { + "name": "Destel Well (2F): chest in ghosts room", + "type": "chest", + "nodeId": "destel_well", + "chestId": 81 + }, + { + "name": "Destel Well (2F): chest in falling platforms room", + "type": "chest", + "nodeId": "destel_well", + "chestId": 82 + }, + { + "name": "Destel Well (2F): right chest in Pockets room", + "type": "chest", + "nodeId": "destel_well", + "chestId": 83 + }, + { + "name": "Destel Well (2F): left chest in Pockets room", + "type": "chest", + "nodeId": "destel_well", + "chestId": 84 + }, + { + "name": "Destel Well (3F): chest in first trapped arena", + "type": "chest", + "nodeId": "destel_well", + "chestId": 85 + }, + { + "name": "Destel Well (3F): chest in trapped giants room", + "type": "chest", + "nodeId": "destel_well", + "chestId": 86 + }, + { + "name": "Destel Well (3F): chest in second trapped arena", + "type": "chest", + "nodeId": "destel_well", + "chestId": 87 + }, + { + "name": "Destel Well (4F): top chest in room before boss", + "type": "chest", + "nodeId": "destel_well", + "chestId": 88 + }, + { + "name": "Destel Well (4F): left chest in room before boss", + "type": "chest", + "nodeId": "destel_well", + "chestId": 89 + }, + { + "name": "Destel Well (4F): bottom chest in room before boss", + "type": "chest", + "nodeId": "destel_well", + "chestId": 90 + }, + { + "name": "Destel Well (4F): right chest in room before boss", + "type": "chest", + "nodeId": "destel_well", + "chestId": 91 + }, + { + "name": "Lake Shrine (-1F): chest in crate room near green golem spinner", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 92 + }, + { + "name": "Lake Shrine (-1F): chest in hallway with hole leading downstairs", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 93 + }, + { + "name": "Lake Shrine (-1F): chest in spikeballs hallway near green golem spinner", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 94 + }, + { + "name": "Lake Shrine (-1F): reward chest for golem hopping puzzle", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 95 + }, + { + "name": "Lake Shrine (-2F): chest on room corner accessed by falling from above", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 96 + }, + { + "name": "Lake Shrine (-2F): lower chest in throne room", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 97 + }, + { + "name": "Lake Shrine (-2F): upper chest in throne room", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 98 + }, + { + "name": "Lake Shrine (-3F): chest on floating platform in white golems room", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 99 + }, + { + "name": "Lake Shrine (-3F): chest near Sword of Ice", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 100 + }, + { + "name": "Lake Shrine (-3F): chest in snake trapping puzzle room", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 101 + }, + { + "name": "Lake Shrine (-3F): chest on cube accessed by falling from upstairs", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 102 + }, + { + "name": "Lake Shrine (-3F): chest in watery archway room", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 103 + }, + { + "name": "Lake Shrine (-3F): left reward chest in boss room", + "type": "chest", + "nodeId": "lake_shrine", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 104 + }, + { + "name": "Lake Shrine (-3F): middle reward chest in boss room", + "type": "chest", + "nodeId": "lake_shrine", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 105 + }, + { + "name": "Lake Shrine (-3F): right reward chest in boss room", + "type": "chest", + "nodeId": "lake_shrine", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 106 + }, + { + "name": "Lake Shrine (-3F): chest near golden golems spinner", + "type": "chest", + "nodeId": "lake_shrine", + "chestId": 107 + }, + { + "name": "King Nole's Labyrinth (0F): chest in exterior room", + "type": "chest", + "nodeId": "king_nole_labyrinth_exterior", + "chestId": 108 + }, + { + "name": "King Nole's Labyrinth (0F): left chest in room after key door", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 109 + }, + { + "name": "King Nole's Labyrinth (0F): right chest in room after key door", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 110 + }, + { + "name": "King Nole's Labyrinth (-1F): chest in maze room with healing tile", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 111 + }, + { + "name": "King Nole's Labyrinth (0F): chest in spike balls room", + "type": "chest", + "nodeId": "king_nole_labyrinth_pre_door", + "chestId": 112 + }, + { + "name": "King Nole's Labyrinth (-1F): right chest in 3-chest dark room (left side)", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 113 + }, + { + "name": "King Nole's Labyrinth (-1F): chest in 3-chest dark room (right side)", + "type": "chest", + "nodeId": "king_nole_labyrinth_pre_door", + "chestId": 114 + }, + { + "name": "King Nole's Labyrinth (-1F): left chest in 3-chest dark room (left side)", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 115 + }, + { + "name": "King Nole's Labyrinth (-1F): chest in maze room with two buttons", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 116 + }, + { + "name": "King Nole's Labyrinth (-1F): upper chest in lantern room", + "type": "chest", + "nodeId": "king_nole_labyrinth_pre_door", + "chestId": 117 + }, + { + "name": "King Nole's Labyrinth (-1F): lower chest in lantern room", + "type": "chest", + "nodeId": "king_nole_labyrinth_pre_door", + "chestId": 118 + }, + { + "name": "King Nole's Labyrinth (-1F): chest in ice shortcut room", + "type": "chest", + "nodeId": "king_nole_labyrinth_pre_door", + "chestId": 119 + }, + { + "name": "King Nole's Labyrinth (-2F): chest in save room", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 120 + }, + { + "name": "King Nole's Labyrinth (-1F): chest in room with button and crates stairway", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 121 + }, + { + "name": "King Nole's Labyrinth (-3F): first chest before Firedemon", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "hints": [ + "in a very hot place" + ], + "chestId": 122 + }, + { + "name": "King Nole's Labyrinth (-3F): second chest before Firedemon", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "hints": [ + "in a very hot place" + ], + "chestId": 123 + }, + { + "name": "King Nole's Labyrinth (-3F): reward chest for beating Firedemon", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "hints": [ + "kept by a threatening guardian", + "in a very hot place" + ], + "chestId": 124 + }, + { + "name": "King Nole's Labyrinth (-2F): chest in four buttons room", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 125 + }, + { + "name": "King Nole's Labyrinth (-3F): first chest after falling from raft", + "type": "chest", + "nodeId": "king_nole_labyrinth_raft", + "chestId": 126 + }, + { + "name": "King Nole's Labyrinth (-3F): left chest in room before Spinner", + "type": "chest", + "nodeId": "king_nole_labyrinth_raft", + "chestId": 127 + }, + { + "name": "King Nole's Labyrinth (-3F): right chest in room before Spinner", + "type": "chest", + "nodeId": "king_nole_labyrinth_raft", + "chestId": 128 + }, + { + "name": "King Nole's Labyrinth (-3F): reward chest for beating Spinner", + "type": "chest", + "nodeId": "king_nole_labyrinth_raft", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 129 + }, + { + "name": "King Nole's Labyrinth (-3F): chest in room after Spinner", + "type": "chest", + "nodeId": "king_nole_labyrinth_raft", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 130 + }, + { + "name": "King Nole's Labyrinth (-3F): chest in room before Miro", + "type": "chest", + "nodeId": "king_nole_labyrinth_path_to_palace", + "hints": [ + "close to a waterfall" + ], + "chestId": 131 + }, + { + "name": "King Nole's Labyrinth (-3F): reward chest for beating Miro", + "type": "chest", + "nodeId": "king_nole_labyrinth_path_to_palace", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 132 + }, + { + "name": "King Nole's Labyrinth (-3F): chest in hands room", + "type": "chest", + "nodeId": "king_nole_labyrinth_post_door", + "chestId": 133 + }, + { + "name": "Route between Gumi and Ryuma: chest on the way to Swordsman Kado", + "type": "chest", + "nodeId": "route_gumi_ryuma", + "chestId": 134 + }, + { + "name": "Route between Massan and Gumi: chest on cliff", + "type": "chest", + "nodeId": "route_massan_gumi", + "hints": [ + "near a swamp" + ], + "chestId": 135 + }, + { + "name": "Route between Mercator and Verla: chest on cliff next to tree", + "type": "chest", + "nodeId": "mir_tower_sector", + "chestId": 136 + }, + { + "name": "Route between Mercator and Verla: chest on cliff next to blocked cave", + "type": "chest", + "nodeId": "mir_tower_sector", + "chestId": 137 + }, + { + "name": "Route between Mercator and Verla: chest near Twinkle village", + "type": "chest", + "nodeId": "mir_tower_sector", + "chestId": 138 + }, + { + "name": "Verla Shore: chest on corner cliff after Verla tunnel", + "type": "chest", + "nodeId": "verla_shore", + "chestId": 139 + }, + { + "name": "Verla Shore: chest on highest cliff after Verla tunnel (accessible through Verla mines)", + "type": "chest", + "nodeId": "verla_shore_cliff", + "chestId": 140 + }, + { + "name": "Route to Mir Tower: chest on cliff accessed by pressing hidden switch", + "type": "chest", + "nodeId": "mir_tower_sector", + "chestId": 141 + }, + { + "name": "Route to Mir Tower: chest behind first sacred tree", + "type": "chest", + "nodeId": "mir_tower_sector_tree_ledge", + "chestId": 142 + }, + { + "name": "Verla Shore: chest behind cabin", + "type": "chest", + "nodeId": "verla_shore", + "hints": [ + "in a well-hidden chest" + ], + "chestId": 143 + }, + { + "name": "Route to Destel: chest in map right after Verla mines exit", + "type": "chest", + "nodeId": "route_verla_destel", + "chestId": 144 + }, + { + "name": "Route to Destel: chest in small platform elevator map", + "type": "chest", + "nodeId": "route_verla_destel", + "chestId": 145 + }, + { + "name": "Route to Mir Tower: chest behind second sacred tree", + "type": "chest", + "nodeId": "mir_tower_sector_tree_coast", + "chestId": 146 + }, + { + "name": "Route to Destel: hidden chest in map right before Destel", + "type": "chest", + "nodeId": "route_verla_destel", + "hints": [ + "in a well-hidden chest" + ], + "chestId": 147 + }, + { + "name": "Mountainous Area: chest near teleport tree", + "type": "chest", + "nodeId": "mountainous_area", + "chestId": 148 + }, + { + "name": "Mountainous Area: chest on right side of map before the bridge", + "type": "chest", + "nodeId": "mountainous_area", + "chestId": 149 + }, + { + "name": "Mountainous Area: hidden chest in L-shaped path", + "type": "chest", + "nodeId": "mountainous_area", + "hints": [ + "in a well-hidden chest" + ], + "chestId": 150 + }, + { + "name": "Mountainous Area: hidden chest in uppermost path", + "type": "chest", + "nodeId": "mountainous_area", + "hints": [ + "in a well-hidden chest" + ], + "chestId": 151 + }, + { + "name": "Mountainous Area: isolated chest on cliff in bridge map", + "type": "chest", + "nodeId": "mountainous_area", + "chestId": 152 + }, + { + "name": "Mountainous Area: left chest on wall in bridge map", + "type": "chest", + "nodeId": "mountainous_area", + "chestId": 153 + }, + { + "name": "Mountainous Area: right chest on wall in bridge map", + "type": "chest", + "nodeId": "mountainous_area", + "chestId": 154 + }, + { + "name": "Mountainous Area: right chest in map before Zak arena", + "type": "chest", + "nodeId": "mountainous_area", + "chestId": 155 + }, + { + "name": "Mountainous Area: left chest in map before Zak arena", + "type": "chest", + "nodeId": "mountainous_area", + "chestId": 156 + }, + { + "name": "Route after Destel: chest on tiny cliff", + "type": "chest", + "nodeId": "route_after_destel", + "chestId": 157 + }, + { + "name": "Route after Destel: hidden chest in map after seeing Duke raft", + "type": "chest", + "nodeId": "route_after_destel", + "hints": [ + "in a well-hidden chest" + ], + "chestId": 158 + }, + { + "name": "Route after Destel: visible chest in map after seeing Duke raft", + "type": "chest", + "nodeId": "route_after_destel", + "chestId": 159 + }, + { + "name": "Mountainous Area: chest hidden under rocky arch", + "type": "chest", + "nodeId": "mountainous_area", + "hints": [ + "in a well-hidden chest" + ], + "chestId": 160 + }, + { + "name": "Route to Lake Shrine: chest on long cliff in crossroads map", + "type": "chest", + "nodeId": "route_lake_shrine", + "chestId": 161 + }, + { + "name": "Route to Lake Shrine: chest on middle cliff in crossroads map (reached from Mountainous Area)", + "type": "chest", + "nodeId": "route_lake_shrine_cliff", + "chestId": 162 + }, + { + "name": "Mountainous Area: chest in map in front of bridge statue", + "type": "chest", + "nodeId": "mountainous_area", + "chestId": 163 + }, + { + "name": "Route to Lake Shrine: right chest in volcano", + "type": "chest", + "nodeId": "route_lake_shrine", + "chestId": 164 + }, + { + "name": "Route to Lake Shrine: left chest in volcano", + "type": "chest", + "nodeId": "route_lake_shrine", + "chestId": 165 + }, + { + "name": "Mountainous Area Cave: chest in small hidden room", + "type": "chest", + "nodeId": "mountainous_area", + "hints": [ + "in a small cave", + "in a well-hidden chest", + "in a cave in the mountains" + ], + "chestId": 166 + }, + { + "name": "Mountainous Area Cave: chest in small visible room", + "type": "chest", + "nodeId": "mountainous_area", + "hints": [ + "in a small cave", + "in a cave in the mountains" + ], + "chestId": 167 + }, + { + "name": "Greenmaze: chest on path to Cutter", + "type": "chest", + "nodeId": "greenmaze_cutter", + "chestId": 168 + }, + { + "name": "Greenmaze: chest on cliff near the swamp", + "type": "chest", + "nodeId": "greenmaze_pre_whistle", + "chestId": 169 + }, + { + "name": "Greenmaze: chest between Sunstone and Massan shortcut", + "type": "chest", + "nodeId": "greenmaze_post_whistle", + "chestId": 170 + }, + { + "name": "Greenmaze: chest in mages room", + "type": "chest", + "nodeId": "greenmaze_pre_whistle", + "chestId": 171 + }, + { + "name": "Greenmaze: left chest in elbow cave", + "type": "chest", + "nodeId": "greenmaze_pre_whistle", + "chestId": 172 + }, + { + "name": "Greenmaze: right chest in elbow cave", + "type": "chest", + "nodeId": "greenmaze_pre_whistle", + "chestId": 173 + }, + { + "name": "Greenmaze: chest in waterfall cave", + "type": "chest", + "nodeId": "greenmaze_pre_whistle", + "hints": [ + "close to a waterfall" + ], + "chestId": 174 + }, + { + "name": "Greenmaze: left chest in hidden room behind waterfall", + "type": "chest", + "nodeId": "greenmaze_pre_whistle", + "hints": [ + "close to a waterfall" + ], + "chestId": 175 + }, + { + "name": "Greenmaze: right chest in hidden room behind waterfall", + "type": "chest", + "nodeId": "greenmaze_pre_whistle", + "hints": [ + "close to a waterfall" + ], + "chestId": 176 + }, + { + "name": "Massan: chest triggered by dog statue", + "type": "chest", + "nodeId": "massan", + "hints": [ + "in a well-hidden chest" + ], + "chestId": 177 + }, + { + "name": "Massan: chest in house nearest to elder house", + "type": "chest", + "nodeId": "massan", + "chestId": 178 + }, + { + "name": "Massan: chest in middle house", + "type": "chest", + "nodeId": "massan", + "chestId": 179 + }, + { + "name": "Massan: chest in house farthest from elder house", + "type": "chest", + "nodeId": "massan", + "chestId": 180 + }, + { + "name": "Gumi: chest on top of bed in house", + "type": "chest", + "nodeId": "gumi", + "chestId": 181 + }, + { + "name": "Gumi: chest in elder house after saving Fara", + "type": "chest", + "nodeId": "gumi_after_swamp_shrine", + "chestId": 182 + }, + { + "name": "Ryuma: chest in mayor's house", + "type": "chest", + "nodeId": "ryuma", + "chestId": 183 + }, + { + "name": "Ryuma: chest in repaired lighthouse", + "type": "chest", + "nodeId": "ryuma_lighthouse_repaired", + "chestId": 184 + }, + { + "name": "Crypt: chest in main room", + "type": "chest", + "nodeId": "crypt", + "chestId": 185 + }, + { + "name": "Crypt: reward chest", + "type": "chest", + "nodeId": "crypt", + "chestId": 186 + }, + { + "name": "Mercator: hidden casino chest", + "type": "chest", + "nodeId": "mercator_casino", + "hints": [ + "hidden in the depths of Mercator", + "in a well-hidden chest" + ], + "chestId": 191 + }, + { + "name": "Mercator: chest in Greenpea's house", + "type": "chest", + "nodeId": "mercator", + "chestId": 192 + }, + { + "name": "Mercator: chest in grandma's house (pot shelving trial)", + "type": "chest", + "nodeId": "mercator", + "chestId": 193 + }, + { + "name": "Verla: chest in well after beating Marley", + "type": "chest", + "nodeId": "verla_after_mines", + "hints": [ + "in a well-hidden chest" + ], + "chestId": 194 + }, + { + "name": "Destel: chest in inn next to innkeeper", + "type": "chest", + "nodeId": "destel", + "chestId": 196 + }, + { + "name": "Mir Tower: timed jump trial chest", + "type": "chest", + "nodeId": "mir_tower_pre_garlic", + "chestId": 197 + }, + { + "name": "Mir Tower: chest after mimic room", + "type": "chest", + "nodeId": "mir_tower_pre_garlic", + "chestId": 198 + }, + { + "name": "Mir Tower: mimic room chest #1", + "type": "chest", + "nodeId": "mir_tower_pre_garlic", + "chestId": 199 + }, + { + "name": "Mir Tower: mimic room chest #2", + "type": "chest", + "nodeId": "mir_tower_pre_garlic", + "chestId": 200 + }, + { + "name": "Mir Tower: mimic room chest #3", + "type": "chest", + "nodeId": "mir_tower_pre_garlic", + "chestId": 201 + }, + { + "name": "Mir Tower: mimic room chest #4", + "type": "chest", + "nodeId": "mir_tower_pre_garlic", + "chestId": 202 + }, + { + "name": "Mir Tower: chest in mushroom pit room", + "type": "chest", + "nodeId": "mir_tower_pre_garlic", + "chestId": 203 + }, + { + "name": "Mir Tower: chest in room next to mummy switch room", + "type": "chest", + "nodeId": "mir_tower_pre_garlic", + "chestId": 204 + }, + { + "name": "Mir Tower: chest in library accessible from teleporter maze", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "chestId": 205 + }, + { + "name": "Mir Tower: hidden chest in room before library", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "hints": [ + "in a well-hidden chest" + ], + "chestId": 206 + }, + { + "name": "Mir Tower: chest in falling spikeballs room", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "chestId": 207 + }, + { + "name": "Mir Tower: chest in timed challenge room", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "chestId": 208 + }, + { + "name": "Mir Tower: chest in room where Miro closes the door", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "chestId": 209 + }, + { + "name": "Mir Tower: chest after room where Miro closes the door", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "chestId": 210 + }, + { + "name": "Mir Tower: reward chest", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 211 + }, + { + "name": "Mir Tower: right chest in reward room", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 212 + }, + { + "name": "Mir Tower: left chest in reward room", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 213 + }, + { + "name": "Mir Tower: chest behind wall accessible after beating Mir", + "type": "chest", + "nodeId": "mir_tower_post_garlic", + "hints": [ + "kept by a threatening guardian" + ], + "chestId": 214 + }, + { + "name": "Witch Helga's Hut: end chest", + "type": "chest", + "nodeId": "helga_hut", + "chestId": 215 + }, + { + "name": "Massan Cave: right chest", + "type": "chest", + "nodeId": "massan_cave", + "chestId": 216 + }, + { + "name": "Massan Cave: left chest", + "type": "chest", + "nodeId": "massan_cave", + "chestId": 217 + }, + { + "name": "Tibor: reward chest after boss", + "type": "chest", + "nodeId": "tibor", + "chestId": 218 + }, + { + "name": "Tibor: chest in spike balls room", + "type": "chest", + "nodeId": "tibor", + "chestId": 219 + }, + { + "name": "Tibor: left chest on 2 chest group", + "type": "chest", + "nodeId": "tibor", + "chestId": 220 + }, + { + "name": "Tibor: right chest on 2 chest group", + "type": "chest", + "nodeId": "tibor", + "chestId": 221 + }, + { + "name": "Gumi: item on furniture in elder's house", + "type": "ground", + "nodeId": "gumi", + "entity": {"mapId": 605, "entityId": 2}, + "groundItemId": 1 + }, + { + "name": "Greenmaze: item behind trees requiring Cutter", + "type": "ground", + "nodeId": "greenmaze_post_whistle", + "entity": {"mapId": 564, "entityId": 0}, + "groundItemId": 2 + }, + { + "name": "Verla Mines: item in the corner of lava filled room", + "type": "ground", + "nodeId": "verla_mines", + "hints": [ + "in a very hot place" + ], + "entity": {"mapId": 263, "entityId": 7}, + "groundItemId": 3 + }, + { + "name": "Lake Shrine (-3F): item on ground at the SE exit of the golden golems roundabout", + "type": "ground", + "nodeId": "lake_shrine", + "entity": {"mapId": 333, "entityId": 0}, + "groundItemId": 4 + }, + { + "name": "King Nole's Labyrinth (-3F): item on ground behind waterfall after beating Spinner", + "type": "ground", + "nodeId": "king_nole_labyrinth_raft", + "hints": [ + "kept by a threatening guardian" + ], + "entity": {"mapId": 411, "entityId": 0}, + "groundItemId": 5 + }, + { + "name": "Destel Well: item on platform revealed after beating Quake", + "type": "ground", + "nodeId": "destel_well", + "hints": [ + "kept by a threatening guardian" + ], + "entity": {"mapId": 288, "entityId": 0}, + "groundItemId": 6 + }, + { + "name": "King Nole's Labyrinth (-1F): item on ground in ninjas room", + "type": "ground", + "nodeId": "king_nole_labyrinth_post_door", + "entity": {"mapId": 374, "entityId": 3}, + "groundItemId": 7 + }, + { + "name": "Massan Cave: item on ground in treasure room", + "type": "ground", + "nodeId": "massan_cave", + "entity": {"mapId": 807, "entityId": 4}, + "groundItemId": 8 + }, + { + "name": "King Nole's Labyrinth (-3F): item on floating hands", + "type": "ground", + "nodeId": "king_nole_labyrinth_post_door", + "entity": {"mapId": 418, "entityId": 0}, + "groundItemId": 9 + }, + { + "name": "Lake Shrine (-3F): isolated item on ground requiring raised platform to reach", + "type": "ground", + "nodeId": "lake_shrine", + "entities": [ + {"mapId": 344, "entityId": 0}, + {"mapId": 345, "entityId": 0} + ], + "groundItemId": 10 + }, + { + "name": "King Nole's Labyrinth (-2F): item on ground after falling from exterior room", + "type": "ground", + "nodeId": "king_nole_labyrinth_fall_from_exterior", + "entity": {"mapId": 363, "entityId": 0}, + "groundItemId": 11 + }, + { + "name": "Route after Destel: item on ground on the cliff", + "type": "ground", + "nodeId": "route_after_destel", + "entity": {"mapId": 483, "entityId": 0}, + "groundItemId": 12 + }, + { + "name": "Mountainous Area cave: item on ground behind hidden path", + "type": "ground", + "nodeId": "mountainous_area", + "hints": [ + "in a small cave", + "in a cave in the mountains" + ], + "entity": {"mapId": 553, "entityId": 0}, + "groundItemId": 13 + }, + { + "name": "Witch Helga's Hut: item on furniture", + "type": "ground", + "nodeId": "helga_hut", + "entity": {"mapId": 479, "entityId": 1}, + "groundItemId": 14 + }, + { + "name": "King Nole's Labyrinth (-3F): item on ground climbing back from Firedemon", + "type": "ground", + "nodeId": "king_nole_labyrinth_post_door", + "hints": [ + "in a very hot place" + ], + "entity": {"mapId": 399, "entityId": 0}, + "groundItemId": 15 + }, + { + "name": "Mercator: falling item in castle court", + "type": "ground", + "nodeId": "mercator", + "entity": {"mapId": 32, "entityId": 2}, + "groundItemId": 16 + }, + { + "name": "Lake Shrine (-2F): north item on ground in quadruple items room", + "type": "ground", + "nodeId": "lake_shrine", + "entity": {"mapId": 318, "entityId": 0}, + "groundItemId": 17 + }, + { + "name": "Lake Shrine (-2F): south item on ground in quadruple items room", + "type": "ground", + "nodeId": "lake_shrine", + "entity": {"mapId": 318, "entityId": 1}, + "groundItemId": 18 + }, + { + "name": "Lake Shrine (-2F): west item on ground in quadruple items room", + "type": "ground", + "nodeId": "lake_shrine", + "entity": {"mapId": 318, "entityId": 2}, + "groundItemId": 19 + }, + { + "name": "Lake Shrine (-2F): east item on ground in quadruple items room", + "type": "ground", + "nodeId": "lake_shrine", + "entity": {"mapId": 318, "entityId": 3}, + "groundItemId": 20 + }, + { + "name": "Twinkle Village: first item on ground", + "type": "ground", + "nodeId": "twinkle_village", + "entity": {"mapId": 462, "entityId": 5}, + "groundItemId": 21 + }, + { + "name": "Twinkle Village: second item on ground", + "type": "ground", + "nodeId": "twinkle_village", + "entity": {"mapId": 462, "entityId": 4}, + "groundItemId": 22 + }, + { + "name": "Twinkle Village: third item on ground", + "type": "ground", + "nodeId": "twinkle_village", + "entity": {"mapId": 462, "entityId": 3}, + "groundItemId": 23 + }, + { + "name": "Mir Tower: Priest room item #1", + "type": "ground", + "nodeId": "mir_tower_post_garlic", + "entity": {"mapId": 775, "entityId": 7}, + "groundItemId": 24 + }, + { + "name": "Mir Tower: Priest room item #2", + "type": "ground", + "nodeId": "mir_tower_post_garlic", + "entity": {"mapId": 775, "entityId": 6}, + "groundItemId": 25 + }, + { + "name": "Mir Tower: Priest room item #3", + "type": "ground", + "nodeId": "mir_tower_post_garlic", + "entity": {"mapId": 775, "entityId": 1}, + "groundItemId": 26 + }, + { + "name": "King Nole's Labyrinth (-2F): Left item dropped by sacred tree", + "type": "ground", + "nodeId": "king_nole_labyrinth_sacred_tree", + "entity": {"mapId": 415, "entityId": 2}, + "groundItemId": 27 + }, + { + "name": "King Nole's Labyrinth (-2F): Right item dropped by sacred tree", + "type": "ground", + "nodeId": "king_nole_labyrinth_sacred_tree", + "entity": {"mapId": 415, "entityId": 1}, + "groundItemId": 28 + }, + { + "name": "King Nole's Labyrinth (-3F): First item on ground before Firedemon", + "type": "ground", + "nodeId": "king_nole_labyrinth_post_door", + "hints": [ + "in a very hot place" + ], + "entity": {"mapId": 400, "entityId": 0}, + "groundItemId": 29 + }, + { + "name": "Massan: Shop item #1", + "type": "shop", + "nodeId": "massan", + "entity": {"mapId": 596, "entityId": 1}, + "shopItemId": 1 + }, + { + "name": "Massan: Shop item #2", + "type": "shop", + "nodeId": "massan", + "entity": {"mapId": 596, "entityId": 2}, + "shopItemId": 2 + }, + { + "name": "Massan: Shop item #3", + "type": "shop", + "nodeId": "massan", + "entity": {"mapId": 596, "entityId": 3}, + "shopItemId": 3 + }, + { + "name": "Gumi: Inn item #1", + "type": "shop", + "nodeId": "gumi", + "entity": {"mapId": 608, "entityId": 4}, + "shopItemId": 4 + }, + { + "name": "Gumi: Inn item #2", + "type": "shop", + "nodeId": "gumi", + "entity": {"mapId": 608, "entityId": 2}, + "shopItemId": 5 + }, + { + "name": "Ryuma: Shop item #1", + "type": "shop", + "nodeId": "ryuma_after_thieves_hideout", + "entity": {"mapId": 615, "entityId": 2}, + "shopItemId": 6 + }, + { + "name": "Ryuma: Shop item #2", + "type": "shop", + "nodeId": "ryuma_after_thieves_hideout", + "entity": {"mapId": 615, "entityId": 3}, + "shopItemId": 7 + }, + { + "name": "Ryuma: Shop item #3", + "type": "shop", + "nodeId": "ryuma_after_thieves_hideout", + "entity": {"mapId": 615, "entityId": 4}, + "shopItemId": 8 + }, + { + "name": "Ryuma: Shop item #4", + "type": "shop", + "nodeId": "ryuma_after_thieves_hideout", + "entity": {"mapId": 615, "entityId": 5}, + "shopItemId": 9 + }, + { + "name": "Ryuma: Shop item #5", + "type": "shop", + "nodeId": "ryuma_after_thieves_hideout", + "entity": {"mapId": 615, "entityId": 6}, + "shopItemId": 10 + }, + { + "name": "Ryuma: Inn item", + "type": "shop", + "nodeId": "ryuma", + "entity": {"mapId": 624, "entityId": 3}, + "shopItemId": 11 + }, + { + "name": "Mercator: Shop item #1", + "type": "shop", + "nodeId": "mercator", + "entity": {"mapId": 679, "entityId": 1}, + "shopItemId": 12 + }, + { + "name": "Mercator: Shop item #2", + "type": "shop", + "nodeId": "mercator", + "entity": {"mapId": 679, "entityId": 2}, + "shopItemId": 13 + }, + { + "name": "Mercator: Shop item #3", + "type": "shop", + "nodeId": "mercator", + "entity": {"mapId": 679, "entityId": 3}, + "shopItemId": 14 + }, + { + "name": "Mercator: Shop item #4", + "type": "shop", + "nodeId": "mercator", + "entity": {"mapId": 679, "entityId": 4}, + "shopItemId": 15 + }, + { + "name": "Mercator: Shop item #5", + "type": "shop", + "nodeId": "mercator", + "entity": {"mapId": 679, "entityId": 5}, + "shopItemId": 16 + }, + { + "name": "Mercator: Shop item #6", + "type": "shop", + "nodeId": "mercator", + "entity": {"mapId": 679, "entityId": 6}, + "shopItemId": 17 + }, + { + "name": "Mercator: Special shop item #1", + "type": "shop", + "nodeId": "mercator_special_shop", + "entity": {"mapId": 696, "entityId": 1}, + "shopItemId": 18 + }, + { + "name": "Mercator: Special shop item #2", + "type": "shop", + "nodeId": "mercator_special_shop", + "entity": {"mapId": 696, "entityId": 2}, + "shopItemId": 19 + }, + { + "name": "Mercator: Special shop item #3", + "type": "shop", + "nodeId": "mercator_special_shop", + "entity": {"mapId": 696, "entityId": 3}, + "shopItemId": 20 + }, + { + "name": "Mercator: Special shop item #4", + "type": "shop", + "nodeId": "mercator_special_shop", + "entity": {"mapId": 696, "entityId": 4}, + "shopItemId": 21 + }, + { + "name": "Mercator: Docks shop item #1", + "type": "shop", + "nodeId": "mercator_repaired_docks", + "entities": [ + {"mapId": 644, "entityId": 3}, + {"mapId": 643, "entityId": 9} + ], + "shopItemId": 22 + }, + { + "name": "Mercator: Docks shop item #2", + "type": "shop", + "nodeId": "mercator_repaired_docks", + "entities": [ + {"mapId": 644, "entityId": 4}, + {"mapId": 643, "entityId": 10} + ], + "shopItemId": 23 + }, + { + "name": "Mercator: Docks shop item #3", + "type": "shop", + "nodeId": "mercator_repaired_docks", + "entities": [ + {"mapId": 644, "entityId": 5}, + {"mapId": 643, "entityId": 11} + ], + "shopItemId": 24 + }, + { + "name": "Verla: Shop item #1", + "type": "shop", + "nodeId": "verla", + "entities": [ + {"mapId": 719, "entityId": 0}, + {"mapId": 720, "entityId": 1} + ], + "shopItemId": 25 + }, + { + "name": "Verla: Shop item #2", + "type": "shop", + "nodeId": "verla", + "entities": [ + {"mapId": 719, "entityId": 1}, + {"mapId": 720, "entityId": 2} + ], + "shopItemId": 26 + }, + { + "name": "Verla: Shop item #3", + "type": "shop", + "nodeId": "verla", + "entities": [ + {"mapId": 719, "entityId": 2}, + {"mapId": 720, "entityId": 3} + ], + "shopItemId": 27 + }, + { + "name": "Verla: Shop item #4", + "type": "shop", + "nodeId": "verla", + "entities": [ + {"mapId": 719, "entityId": 4}, + {"mapId": 720, "entityId": 4} + ], + "shopItemId": 28 + }, + { + "name": "Verla: Shop item #5 (extra item after saving town)", + "type": "shop", + "nodeId": "verla_after_mines", + "entity": {"mapId": 720, "entityId": 5}, + "shopItemId": 29 + }, + { + "name": "Route from Verla to Destel: Kelketo shop item #1", + "type": "shop", + "nodeId": "route_verla_destel", + "entity": {"mapId": 517, "entityId": 1}, + "shopItemId": 30 + }, + { + "name": "Route from Verla to Destel: Kelketo shop item #2", + "type": "shop", + "nodeId": "route_verla_destel", + "entity": {"mapId": 517, "entityId": 2}, + "shopItemId": 31 + }, + { + "name": "Route from Verla to Destel: Kelketo shop item #3", + "type": "shop", + "nodeId": "route_verla_destel", + "entity": {"mapId": 517, "entityId": 3}, + "shopItemId": 32 + }, + { + "name": "Route from Verla to Destel: Kelketo shop item #4", + "type": "shop", + "nodeId": "route_verla_destel", + "entity": {"mapId": 517, "entityId": 4}, + "shopItemId": 33 + }, + { + "name": "Route from Verla to Destel: Kelketo shop item #5", + "type": "shop", + "nodeId": "route_verla_destel", + "entity": {"mapId": 517, "entityId": 5}, + "shopItemId": 34 + }, + { + "name": "Destel: Inn item", + "type": "shop", + "nodeId": "destel", + "entity": {"mapId": 729, "entityId": 2}, + "shopItemId": 35 + }, + { + "name": "Destel: Shop item #1", + "type": "shop", + "nodeId": "destel", + "entity": {"mapId": 733, "entityId": 1}, + "shopItemId": 36 + }, + { + "name": "Destel: Shop item #2", + "type": "shop", + "nodeId": "destel", + "entity": {"mapId": 733, "entityId": 2}, + "shopItemId": 37 + }, + { + "name": "Destel: Shop item #3", + "type": "shop", + "nodeId": "destel", + "entity": {"mapId": 733, "entityId": 3}, + "shopItemId": 38 + }, + { + "name": "Destel: Shop item #4", + "type": "shop", + "nodeId": "destel", + "entity": {"mapId": 733, "entityId": 4}, + "shopItemId": 39 + }, + { + "name": "Destel: Shop item #5", + "type": "shop", + "nodeId": "destel", + "entity": {"mapId": 733, "entityId": 5}, + "shopItemId": 40 + }, + { + "name": "Route to Lake Shrine: Greedly's shop item #1", + "type": "shop", + "nodeId": "route_lake_shrine", + "entity": {"mapId": 526, "entityId": 0}, + "shopItemId": 41 + }, + { + "name": "Route to Lake Shrine: Greedly's shop item #2", + "type": "shop", + "nodeId": "route_lake_shrine", + "entity": {"mapId": 526, "entityId": 2}, + "shopItemId": 42 + }, + { + "name": "Route to Lake Shrine: Greedly's shop item #3", + "type": "shop", + "nodeId": "route_lake_shrine", + "entity": {"mapId": 526, "entityId": 3}, + "shopItemId": 43 + }, + { + "name": "Route to Lake Shrine: Greedly's shop item #4", + "type": "shop", + "nodeId": "route_lake_shrine", + "entity": {"mapId": 526, "entityId": 4}, + "shopItemId": 44 + }, + { + "name": "Kazalt: Shop item #1", + "type": "shop", + "nodeId": "kazalt", + "entity": {"mapId": 747, "entityId": 0}, + "shopItemId": 45 + }, + { + "name": "Kazalt: Shop item #2", + "type": "shop", + "nodeId": "kazalt", + "entity": {"mapId": 747, "entityId": 2}, + "shopItemId": 46 + }, + { + "name": "Kazalt: Shop item #3", + "type": "shop", + "nodeId": "kazalt", + "entity": {"mapId": 747, "entityId": 3}, + "shopItemId": 47 + }, + { + "name": "Kazalt: Shop item #4", + "type": "shop", + "nodeId": "kazalt", + "entity": {"mapId": 747, "entityId": 4}, + "shopItemId": 48 + }, + { + "name": "Kazalt: Shop item #5", + "type": "shop", + "nodeId": "kazalt", + "entity": {"mapId": 747, "entityId": 5}, + "shopItemId": 49 + }, + { + "name": "Massan: Elder reward after freeing Fara in Swamp Shrine", + "type": "reward", + "nodeId": "massan_after_swamp_shrine", + "address": 162337, + "flag": {"byte": "0x1004", "bit": 2}, + "rewardId": 0 + }, + { + "name": "Lake Shrine: Mir reward after beating Duke", + "type": "reward", + "nodeId": "lake_shrine", + "address": 166463, + "flag": {"byte": "0x1003", "bit": 0}, + "rewardId": 1 + }, + { + "name": "Greenmaze: Cutter reward for saving Einstein", + "type": "reward", + "nodeId": "greenmaze_cutter", + "address": 166021, + "flag": {"byte": "0x1024", "bit": 4}, + "rewardId": 2 + }, + { + "name": "Mountainous Area: Zak reward after fighting", + "type": "reward", + "nodeId": "mountainous_area", + "hints": [ + "kept by a threatening guardian" + ], + "address": 166515, + "flag": {"byte": "0x1027", "bit": 0}, + "rewardId": 3 + }, + { + "name": "Route between Gumi and Ryuma: Swordsman Kado reward", + "type": "reward", + "nodeId": "route_gumi_ryuma", + "address": 166219, + "flag": {"byte": "0x101B", "bit": 7}, + "rewardId": 4 + }, + { + "name": "Greenmaze: dwarf hidden in the trees", + "type": "reward", + "nodeId": "greenmaze_pre_whistle", + "address": 166111, + "flag": {"byte": "0x1022", "bit": 7}, + "rewardId": 5 + }, + { + "name": "Mercator: Arthur reward (in castle throne room)", + "type": "reward", + "nodeId": "mercator", + "address": 164191, + "flag": {"byte": "0x101B", "bit": 6}, + "rewardId": 6 + }, + { + "name": "Mercator: Fahl's dojo challenge reward", + "type": "reward", + "nodeId": "mercator", + "address": 165029, + "flag": {"byte": "0x101C", "bit": 4}, + "rewardId": 7 + }, + { + "name": "Ryuma: Mayor's first reward", + "type": "reward", + "nodeId": "ryuma_after_thieves_hideout", + "address": 164731, + "flag": {"byte": "0x1004", "bit": 3}, + "rewardId": 8 + }, + { + "name": "Ryuma: Mayor's second reward", + "type": "reward", + "nodeId": "ryuma_after_thieves_hideout", + "address": 164735, + "flag": {"byte": "0x1004", "bit": 3}, + "rewardId": 9 + } +] diff --git a/worlds/landstalker/data/world_node.py b/worlds/landstalker/data/world_node.py new file mode 100644 index 000000000000..f786f9613fba --- /dev/null +++ b/worlds/landstalker/data/world_node.py @@ -0,0 +1,411 @@ +WORLD_NODES_JSON = { + "massan": { + "name": "Massan", + "hints": [ + "in a village", + "in a region inhabited by bears", + "in the village of Massan" + ] + }, + "massan_cave": { + "name": "Massan Cave", + "hints": [ + "in a large cave", + "in a region inhabited by bears", + "in Massan cave" + ] + }, + "route_massan_gumi": { + "name": "Route between Massan and Gumi", + "hints": [ + "on a route", + "in a region inhabited by bears", + "between Massan and Gumi" + ] + }, + "waterfall_shrine": { + "name": "Waterfall Shrine", + "hints": [ + "in a shrine", + "close to a waterfall", + "in a region inhabited by bears", + "in Waterfall Shrine" + ] + }, + "swamp_shrine": { + "name": "Swamp Shrine", + "hints": [ + "in a shrine", + "near a swamp", + "in a region inhabited by bears", + "in Swamp Shrine" + ] + }, + "massan_after_swamp_shrine": { + "name": "Massan (after Swamp Shrine)", + "hints": [ + "in a village", + "in a region inhabited by bears", + "in the village of Massan" + ] + }, + "gumi_after_swamp_shrine": { + "name": "Gumi (after Swamp Shrine)", + "hints": [ + "in a village", + "in a region inhabited by bears", + "in the village of Gumi" + ] + }, + "gumi": { + "name": "Gumi", + "hints": [ + "in a village", + "in a region inhabited by bears", + "in the village of Gumi" + ] + }, + "route_gumi_ryuma": { + "name": "Route from Gumi to Ryuma", + "hints": [ + "on a route", + "in a region inhabited by bears", + "between Gumi and Ryuma" + ] + }, + "tibor": { + "name": "Tibor", + "hints": [ + "among the trees", + "inside the elder tree called Tibor" + ] + }, + "ryuma": { + "name": "Ryuma", + "hints": [ + "in a town", + "in the town of Ryuma" + ] + }, + "ryuma_after_thieves_hideout": { + "name": "Ryuma (after Thieves Hideout)", + "hints": [ + "in a town", + "in the town of Ryuma" + ] + }, + "ryuma_lighthouse_repaired": { + "name": "Ryuma (repaired lighthouse)", + "hints": [ + "in a town", + "in the town of Ryuma" + ] + }, + "thieves_hideout_pre_key": { + "name": "Thieves Hideout (before keydoor)", + "hints": [ + "close to a waterfall", + "in a large cave", + "in the Thieves' Hideout" + ] + }, + "thieves_hideout_post_key": { + "name": "Thieves Hideout (after keydoor)", + "hints": [ + "close to a waterfall", + "in a large cave", + "in the Thieves' Hideout" + ] + }, + "helga_hut": { + "name": "Witch Helga's Hut", + "hints": [ + "near a swamp", + "in the hut of a witch called Helga" + ] + }, + "mercator": { + "name": "Mercator", + "hints": [ + "in a town", + "in the town of Mercator" + ] + }, + "mercator_repaired_docks": { + "name": "Mercator (docks with repaired lighthouse)", + "hints": [ + "in a town", + "in the town of Mercator" + ] + }, + "mercator_casino": { + "name": "Mercator casino" + }, + "mercator_dungeon": { + "name": "Mercator Dungeon" + }, + "crypt": { + "name": "Crypt", + "hints": [ + "hidden in the depths of Mercator", + "in Mercator crypt" + ] + }, + "mercator_special_shop": { + "name": "Mercator special shop", + "hints": [ + "in a town", + "in the town of Mercator" + ] + }, + "mir_tower_sector": { + "name": "Mir Tower sector", + "hints": [ + "on a route", + "near Mir Tower" + ] + }, + "mir_tower_sector_tree_ledge": { + "name": "Mir Tower sector (ledge behind sacred tree)", + "hints": [ + "on a route", + "among the trees", + "near Mir Tower" + ] + }, + "mir_tower_sector_tree_coast": { + "name": "Mir Tower sector (coast behind sacred tree)", + "hints": [ + "on a route", + "among the trees", + "near Mir Tower" + ] + }, + "twinkle_village": { + "name": "Twinkle village", + "hints": [ + "in a village", + "in Twinkle village" + ] + }, + "mir_tower_pre_garlic": { + "name": "Mir Tower (pre-garlic)", + "hints": [ + "inside a tower", + "in Mir Tower" + ] + }, + "mir_tower_post_garlic": { + "name": "Mir Tower (post-garlic)", + "hints": [ + "inside a tower", + "in Mir Tower" + ] + }, + "greenmaze_pre_whistle": { + "name": "Greenmaze (pre-whistle)", + "hints": [ + "among the trees", + "in the infamous Greenmaze" + ] + }, + "greenmaze_cutter": { + "name": "Greenmaze (Cutter hidden sector)", + "hints": [ + "among the trees", + "in the infamous Greenmaze" + ] + }, + "greenmaze_post_whistle": { + "name": "Greenmaze (post-whistle)", + "hints": [ + "among the trees", + "in the infamous Greenmaze" + ] + }, + "verla_shore": { + "name": "Verla shore", + "hints": [ + "on a route", + "near the town of Verla" + ] + }, + "verla_shore_cliff": { + "name": "Verla shore cliff (accessible from Verla Mines)", + "hints": [ + "on a route", + "near the town of Verla" + ] + }, + "verla": { + "name": "Verla", + "hints": [ + "in a town", + "in the town of Verla" + ] + }, + "verla_after_mines": { + "name": "Verla (after mines)", + "hints": [ + "in a town", + "in the town of Verla" + ] + }, + "verla_mines": { + "name": "Verla Mines", + "hints": [ + "in Verla Mines" + ] + }, + "verla_mines_behind_lava": { + "name": "Verla Mines (behind lava)", + "hints": [ + "in Verla Mines" + ] + }, + "route_verla_destel": { + "name": "Route between Verla and Destel", + "hints": [ + "on a route", + "in Destel region", + "between Verla and Destel" + ] + }, + "destel": { + "name": "Destel", + "hints": [ + "in a village", + "in Destel region", + "in the village of Destel" + ] + }, + "route_after_destel": { + "name": "Route after Destel", + "hints": [ + "on a route", + "near a lake", + "in Destel region", + "on the route to the lake after Destel" + ] + }, + "destel_well": { + "name": "Destel Well", + "hints": [ + "in Destel region", + "in a large cave", + "in Destel Well" + ] + }, + "route_lake_shrine": { + "name": "Route to Lake Shrine", + "hints": [ + "on a route", + "near a lake", + "on the mountainous path to Lake Shrine" + ] + }, + "route_lake_shrine_cliff": { + "name": "Route to Lake Shrine cliff", + "hints": [ + "on a route", + "near a lake", + "on the mountainous path to Lake Shrine" + ] + }, + "lake_shrine": { + "name": "Lake Shrine", + "hints": [ + "in a shrine", + "near a lake", + "in Lake Shrine" + ] + }, + "mountainous_area": { + "name": "Mountainous Area", + "hints": [ + "in a mountainous area" + ] + }, + "king_nole_cave": { + "name": "King Nole's Cave", + "hints": [ + "in a large cave", + "in King Nole's cave" + ] + }, + "kazalt": { + "name": "Kazalt", + "hints": [ + "in King Nole's domain", + "in Kazalt" + ] + }, + "king_nole_labyrinth_pre_door": { + "name": "King Nole's Labyrinth (before door)", + "hints": [ + "in King Nole's domain", + "in King Nole's labyrinth" + ] + }, + "king_nole_labyrinth_post_door": { + "name": "King Nole's Labyrinth (after door)", + "hints": [ + "in King Nole's domain", + "in King Nole's labyrinth" + ] + }, + "king_nole_labyrinth_exterior": { + "name": "King Nole's Labyrinth (exterior)", + "hints": [ + "in King Nole's domain", + "in King Nole's labyrinth" + ] + }, + "king_nole_labyrinth_fall_from_exterior": { + "name": "King Nole's Labyrinth (fall from exterior)", + "hints": [ + "in King Nole's domain", + "in King Nole's labyrinth" + ] + }, + "king_nole_labyrinth_raft_entrance": { + "name": "King Nole's Labyrinth (raft entrance)", + "hints": [ + "in King Nole's domain", + "in King Nole's labyrinth" + ] + }, + "king_nole_labyrinth_raft": { + "name": "King Nole's Labyrinth (raft)", + "hints": [ + "close to a waterfall", + "in King Nole's domain", + "in King Nole's labyrinth" + ] + }, + "king_nole_labyrinth_sacred_tree": { + "name": "King Nole's Labyrinth (sacred tree)", + "hints": [ + "among the trees", + "in King Nole's domain", + "in King Nole's labyrinth" + ] + }, + "king_nole_labyrinth_path_to_palace": { + "name": "King Nole's Labyrinth (path to palace)", + "hints": [ + "in King Nole's domain", + "in King Nole's labyrinth" + ] + }, + "king_nole_palace": { + "name": "King Nole's Palace", + "hints": [ + "in King Nole's domain", + "in King Nole's palace" + ] + }, + "end": { + "name": "The End" + } +} diff --git a/worlds/landstalker/data/world_path.py b/worlds/landstalker/data/world_path.py new file mode 100644 index 000000000000..f7baba358a48 --- /dev/null +++ b/worlds/landstalker/data/world_path.py @@ -0,0 +1,446 @@ +WORLD_PATHS_JSON = [ + { + "fromId": "massan", + "toId": "massan_cave", + "twoWay": True, + "requiredItems": [ + "Axe Magic" + ] + }, + { + "fromId": "massan", + "toId": "massan_after_swamp_shrine", + "requiredNodes": [ + "swamp_shrine" + ] + }, + { + "fromId": "massan", + "toId": "route_massan_gumi", + "twoWay": True + }, + { + "fromId": "route_massan_gumi", + "toId": "waterfall_shrine", + "twoWay": True + }, + { + "fromId": "route_massan_gumi", + "toId": "swamp_shrine", + "twoWay": True, + "weight": 2, + "requiredItems": [ + "Idol Stone" + ] + }, + { + "fromId": "route_massan_gumi", + "toId": "gumi", + "twoWay": True + }, + { + "fromId": "gumi", + "toId": "gumi_after_swamp_shrine", + "requiredNodes": [ + "swamp_shrine" + ] + }, + { + "fromId": "gumi", + "toId": "route_gumi_ryuma" + }, + { + "fromId": "route_gumi_ryuma", + "toId": "ryuma", + "twoWay": True + }, + { + "fromId": "ryuma", + "toId": "ryuma_after_thieves_hideout", + "requiredNodes": [ + "thieves_hideout_post_key" + ] + }, + { + "fromId": "ryuma", + "toId": "ryuma_lighthouse_repaired", + "twoWay": True, + "requiredItems": [ + "Sun Stone" + ] + }, + { + "fromId": "ryuma", + "toId": "thieves_hideout_pre_key", + "twoWay": True + }, + { + "fromId": "thieves_hideout_pre_key", + "toId": "thieves_hideout_post_key", + "requiredItems": [ + "Key" + ] + }, + { + "fromId": "thieves_hideout_post_key", + "toId": "thieves_hideout_pre_key" + }, + { + "fromId": "route_gumi_ryuma", + "toId": "tibor", + "twoWay": True + }, + { + "fromId": "route_gumi_ryuma", + "toId": "helga_hut", + "twoWay": True, + "requiredItems": [ + "Einstein Whistle" + ], + "requiredNodes": [ + "massan" + ] + }, + { + "fromId": "route_gumi_ryuma", + "toId": "mercator", + "twoWay": True, + "weight": 2, + "requiredItems": [ + "Safety Pass" + ] + }, + { + "fromId": "mercator", + "toId": "mercator_dungeon", + "twoWay": True + }, + { + "fromId": "mercator", + "toId": "crypt", + "twoWay": True + }, + { + "fromId": "mercator", + "toId": "mercator_special_shop", + "twoWay": True, + "requiredItems": [ + "Buyer Card" + ] + }, + { + "fromId": "mercator", + "toId": "mercator_casino", + "twoWay": True, + "requiredItems": [ + "Casino Ticket" + ] + }, + { + "fromId": "mercator", + "toId": "mir_tower_sector", + "twoWay": True + }, + { + "fromId": "mir_tower_sector", + "toId": "twinkle_village", + "twoWay": True + }, + { + "fromId": "mir_tower_sector", + "toId": "mir_tower_sector_tree_ledge", + "twoWay": True, + "requiredItems": [ + "Axe Magic" + ] + }, + { + "fromId": "mir_tower_sector", + "toId": "mir_tower_sector_tree_coast", + "twoWay": True, + "requiredItems": [ + "Axe Magic" + ] + }, + { + "fromId": "mir_tower_sector", + "toId": "mir_tower_pre_garlic", + "requiredItems": [ + "Armlet" + ] + }, + { + "fromId": "mir_tower_pre_garlic", + "toId": "mir_tower_sector" + }, + { + "fromId": "mir_tower_pre_garlic", + "toId": "mir_tower_post_garlic", + "requiredItems": [ + "Garlic" + ] + }, + { + "fromId": "mir_tower_post_garlic", + "toId": "mir_tower_pre_garlic" + }, + { + "fromId": "mir_tower_post_garlic", + "toId": "mir_tower_sector" + }, + { + "fromId": "mercator", + "toId": "greenmaze_pre_whistle", + "weight": 2, + "requiredItems": [ + "Key" + ] + }, + { + "fromId": "greenmaze_pre_whistle", + "toId": "greenmaze_post_whistle", + "requiredItems": [ + "Einstein Whistle" + ] + }, + { + "fromId": "greenmaze_pre_whistle", + "toId": "greenmaze_cutter", + "requiredItems": [ + "EkeEke" + ], + "twoWay": True + }, + { + "fromId": "greenmaze_post_whistle", + "toId": "route_massan_gumi" + }, + { + "fromId": "mercator", + "toId": "mercator_repaired_docks", + "requiredNodes": [ + "ryuma_lighthouse_repaired" + ] + }, + { + "fromId": "mercator_repaired_docks", + "toId": "verla_shore" + }, + { + "fromId": "verla_shore", + "toId": "verla", + "twoWay": True + }, + { + "fromId": "verla", + "toId": "verla_after_mines", + "requiredNodes": [ + "verla_mines" + ], + "twoWay": True + }, + { + "fromId": "verla_shore", + "toId": "verla_mines", + "twoWay": True + }, + { + "fromId": "verla_mines", + "toId": "verla_shore_cliff", + "twoWay": True + }, + { + "fromId": "verla_shore_cliff", + "toId": "verla_shore" + }, + { + "fromId": "verla_shore", + "toId": "mir_tower_sector", + "requiredNodes": [ + "verla_mines" + ], + "twoWay": True + }, + { + "fromId": "verla_mines", + "toId": "route_verla_destel" + }, + { + "fromId": "verla_mines", + "toId": "verla_mines_behind_lava", + "twoWay": True, + "requiredItems": [ + "Fireproof" + ] + }, + { + "fromId": "route_verla_destel", + "toId": "destel", + "twoWay": True + }, + { + "fromId": "destel", + "toId": "route_after_destel", + "twoWay": True + }, + { + "fromId": "destel", + "toId": "destel_well", + "twoWay": True + }, + { + "fromId": "destel_well", + "toId": "route_lake_shrine", + "twoWay": True + }, + { + "fromId": "route_lake_shrine", + "toId": "lake_shrine", + "itemsPlacedWhenCrossing": [ + "Sword of Gaia" + ] + }, + { + "fromId": "lake_shrine", + "toId": "route_lake_shrine" + }, + { + "fromId": "lake_shrine", + "toId": "mir_tower_sector" + }, + { + "fromId": "greenmaze_pre_whistle", + "toId": "mountainous_area", + "twoWay": True, + "requiredItems": [ + "Axe Magic" + ] + }, + { + "fromId": "mountainous_area", + "toId": "route_lake_shrine_cliff", + "twoWay": True, + "requiredItems": [ + "Axe Magic" + ] + }, + { + "fromId": "route_lake_shrine_cliff", + "toId": "route_lake_shrine" + }, + { + "fromId": "mountainous_area", + "toId": "king_nole_cave", + "twoWay": True, + "weight": 2, + "requiredItems": [ + "Gola's Eye" + ] + }, + { + "fromId": "king_nole_cave", + "toId": "mercator" + }, + { + "fromId": "king_nole_cave", + "toId": "kazalt", + "itemsPlacedWhenCrossing": [ + "Lithograph" + ] + }, + { + "fromId": "kazalt", + "toId": "king_nole_cave" + }, + { + "fromId": "kazalt", + "toId": "king_nole_labyrinth_pre_door", + "twoWay": True + }, + { + "fromId": "king_nole_labyrinth_pre_door", + "toId": "king_nole_labyrinth_post_door", + "requiredItems": [ + "Key" + ] + }, + { + "fromId": "king_nole_labyrinth_post_door", + "toId": "king_nole_labyrinth_pre_door" + }, + { + "fromId": "king_nole_labyrinth_pre_door", + "toId": "king_nole_labyrinth_exterior", + "requiredItems": [ + "Iron Boots" + ] + }, + { + "fromId": "king_nole_labyrinth_exterior", + "toId": "king_nole_labyrinth_fall_from_exterior", + "requiredItems": [ + "Axe Magic" + ] + }, + { + "fromId": "king_nole_labyrinth_fall_from_exterior", + "toId": "king_nole_labyrinth_pre_door" + }, + { + "fromId": "king_nole_labyrinth_post_door", + "toId": "king_nole_labyrinth_raft_entrance", + "requiredItems": [ + "Snow Spikes" + ] + }, + { + "fromId": "king_nole_labyrinth_raft_entrance", + "toId": "king_nole_labyrinth_post_door" + }, + { + "fromId": "king_nole_labyrinth_raft_entrance", + "toId": "king_nole_labyrinth_raft", + "requiredItems": [ + "Logs" + ] + }, + { + "fromId": "king_nole_labyrinth_raft", + "toId": "king_nole_labyrinth_raft_entrance" + }, + { + "fromId": "king_nole_labyrinth_post_door", + "toId": "king_nole_labyrinth_path_to_palace", + "requiredItems": [ + "Snow Spikes" + ] + }, + { + "fromId": "king_nole_labyrinth_path_to_palace", + "toId": "king_nole_labyrinth_post_door" + }, + { + "fromId": "king_nole_labyrinth_post_door", + "toId": "king_nole_labyrinth_sacred_tree", + "requiredItems": [ + "Axe Magic" + ], + "requiredNodes": [ + "king_nole_labyrinth_raft_entrance" + ] + }, + { + "fromId": "king_nole_labyrinth_path_to_palace", + "toId": "king_nole_palace", + "twoWay": True + }, + { + "fromId": "king_nole_palace", + "toId": "end", + "requiredItems": [ + "Gola's Fang", + "Gola's Horn", + "Gola's Nail" + ] + } +] \ No newline at end of file diff --git a/worlds/landstalker/data/world_region.py b/worlds/landstalker/data/world_region.py new file mode 100644 index 000000000000..3365a9dfa9e2 --- /dev/null +++ b/worlds/landstalker/data/world_region.py @@ -0,0 +1,299 @@ +WORLD_REGIONS_JSON = [ + { + "name": "Massan", + "hintName": "in the village of Massan", + "nodeIds": [ + "massan", + "massan_after_swamp_shrine" + ] + }, + { + "name": "Massan Cave", + "hintName": "in the cave near Massan", + "nodeIds": [ + "massan_cave" + ], + "darkMapIds": [ + 803, 804, 805, 806, 807 + ] + }, + { + "name": "Route between Massan and Gumi", + "canBeHintedAsRequired": False, + "nodeIds": [ + "route_massan_gumi" + ] + }, + { + "name": "Waterfall Shrine", + "hintName": "in the waterfall shrine", + "nodeIds": [ + "waterfall_shrine" + ], + "darkMapIds": [ + 174, 175, 176, 177, 178, 179, 180, 181, 182 + ] + }, + { + "name": "Swamp Shrine", + "hintName": "in the swamp shrine", + "canBeHintedAsRequired": False, + "nodeIds": [ + "swamp_shrine" + ], + "darkMapIds": [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 30 + ] + }, + { + "name": "Gumi", + "hintName": "in the village of Gumi", + "nodeIds": [ + "gumi", + "gumi_after_swamp_shrine" + ] + }, + { + "name": "Route between Gumi and Ryuma", + "canBeHintedAsRequired": False, + "nodeIds": [ + "route_gumi_ryuma" + ] + }, + { + "name": "Tibor", + "hintName": "inside Tibor", + "nodeIds": [ + "tibor" + ], + "darkMapIds": [ + 808, 809, 810, 811, 812, 813, 814, 815 + ] + }, + { + "name": "Ryuma", + "hintName": "in the town of Ryuma", + "nodeIds": [ + "ryuma", + "ryuma_after_thieves_hideout", + "ryuma_lighthouse_repaired" + ] + }, + { + "name": "Thieves Hideout", + "hintName": "in the thieves' hideout", + "nodeIds": [ + "thieves_hideout_pre_key", + "thieves_hideout_post_key" + ], + "darkMapIds": [ + 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 210, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222 + ] + }, + { + "name": "Witch Helga's Hut", + "hintName": "in witch Helga's hut", + "nodeIds": [ + "helga_hut" + ] + }, + { + "name": "Mercator", + "hintName": "in the town of Mercator", + "nodeIds": [ + "mercator", + "mercator_repaired_docks", + "mercator_casino", + "mercator_special_shop" + ] + }, + { + "name": "Crypt", + "hintName": "in the crypt of Mercator", + "nodeIds": [ + "crypt" + ], + "darkMapIds": [ + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659 + ] + }, + { + "name": "Mercator Dungeon", + "hintName": "in the dungeon of Mercator", + "nodeIds": [ + "mercator_dungeon" + ], + "darkMapIds": [ + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 76, 80, 81, 82, 91, 92 + ] + }, + { + "name": "Mir Tower sector", + "hintName": "near Mir Tower", + "canBeHintedAsRequired": False, + "nodeIds": [ + "mir_tower_sector", + "mir_tower_sector_tree_ledge", + "mir_tower_sector_tree_coast", + "twinkle_village" + ] + }, + { + "name": "Mir Tower", + "hintName": "inside Mir Tower", + "canBeHintedAsRequired": False, + "nodeIds": [ + "mir_tower_pre_garlic", + "mir_tower_post_garlic" + ], + "darkMapIds": [ + 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, + 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784 + ] + }, + { + "name": "Greenmaze", + "hintName": "in Greenmaze", + "nodeIds": [ + "greenmaze_pre_whistle", + "greenmaze_post_whistle" + ] + }, + { + "name": "Verla Shore", + "canBeHintedAsRequired": False, + "nodeIds": [ + "verla_shore", + "verla_shore_cliff" + ] + }, + { + "name": "Verla", + "hintName": "in the town of Verla", + "nodeIds": [ + "verla", + "verla_after_mines" + ] + }, + { + "name": "Verla Mines", + "hintName": "in the mines near Verla", + "nodeIds": [ + "verla_mines", + "verla_mines_behind_lava" + ], + "darkMapIds": [ + 227, 228, 229, 230, 231, 232, 233, 234, 235, 237, 239, 240, 241, 242, 243, 244, 246, + 247, 248, 250, 253, 254, 255, 256, 258, 259, 266, 268, 269, 471 + ] + }, + { + "name": "Route between Verla and Destel", + "canBeHintedAsRequired": False, + "nodeIds": [ + "route_verla_destel" + ] + }, + { + "name": "Destel", + "hintName": "in the village of Destel", + "nodeIds": [ + "destel" + ] + }, + { + "name": "Route after Destel", + "canBeHintedAsRequired": False, + "nodeIds": [ + "route_after_destel" + ] + }, + { + "name": "Destel Well", + "hintName": "in Destel well", + "nodeIds": [ + "destel_well" + ], + "darkMapIds": [ + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290 + ] + }, + { + "name": "Route to Lake Shrine", + "canBeHintedAsRequired": False, + "nodeIds": [ + "route_lake_shrine", + "route_lake_shrine_cliff" + ] + }, + { + "name": "Lake Shrine", + "hintName": "in the lake shrine", + "nodeIds": [ + "lake_shrine" + ], + "darkMapIds": [ + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354 + ] + }, + { + "name": "Mountainous Area", + "hintName": "in the mountainous area", + "nodeIds": [ + "mountainous_area" + ] + }, + { + "name": "King Nole's Cave", + "hintName": "in King Nole's cave", + "nodeIds": [ + "king_nole_cave" + ], + "darkMapIds": [ + 145, 147, 150, 152, 154, 155, 156, 158, 160, 161, 162, 164, 166, 170, 171, 172 + ] + }, + { + "name": "Kazalt", + "hintName": "in the hidden town of Kazalt", + "nodeIds": [ + "kazalt" + ] + }, + { + "name": "King Nole's Labyrinth", + "hintName": "in King Nole's labyrinth", + "nodeIds": [ + "king_nole_labyrinth_pre_door", + "king_nole_labyrinth_post_door", + "king_nole_labyrinth_exterior", + "king_nole_labyrinth_fall_from_exterior", + "king_nole_labyrinth_path_to_palace", + "king_nole_labyrinth_raft_entrance", + "king_nole_labyrinth_raft", + "king_nole_labyrinth_sacred_tree" + ], + "darkMapIds": [ + 355, 356, 357, 358, 359, 360, 361, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 405, 406, 408, 409, 410, 411, 412, 413, + 414, 415, 416, 417, 418, 419, 420, 422, 423 + ] + }, + { + "name": "King Nole's Palace", + "hintName": "in King Nole's palace", + "nodeIds": [ + "king_nole_palace", + "end" + ], + "darkMapIds": [ + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138 + ] + } +] \ No newline at end of file diff --git a/worlds/landstalker/data/world_teleport_tree.py b/worlds/landstalker/data/world_teleport_tree.py new file mode 100644 index 000000000000..830f5547201e --- /dev/null +++ b/worlds/landstalker/data/world_teleport_tree.py @@ -0,0 +1,62 @@ +WORLD_TELEPORT_TREES_JSON = [ + [ + { + "name": "Massan tree", + "treeMapId": 512, + "nodeId": "route_massan_gumi" + }, + { + "name": "Tibor tree", + "treeMapId": 534, + "nodeId": "route_gumi_ryuma" + } + ], + [ + { + "name": "Mercator front gate tree", + "treeMapId": 539, + "nodeId": "route_gumi_ryuma" + }, + { + "name": "Verla shore tree", + "treeMapId": 537, + "nodeId": "verla_shore" + } + ], + [ + { + "name": "Destel sector tree", + "treeMapId": 536, + "nodeId": "route_after_destel" + }, + { + "name": "Lake Shrine sector tree", + "treeMapId": 513, + "nodeId": "route_lake_shrine" + } + ], + [ + { + "name": "Mir Tower sector tree", + "treeMapId": 538, + "nodeId": "mir_tower_sector" + }, + { + "name": "Mountainous area tree", + "treeMapId": 535, + "nodeId": "mountainous_area" + } + ], + [ + { + "name": "Greenmaze entrance tree", + "treeMapId": 510, + "nodeId": "greenmaze_pre_whistle" + }, + { + "name": "Greenmaze end tree", + "treeMapId": 511, + "nodeId": "greenmaze_post_whistle" + } + ] +] \ No newline at end of file diff --git a/worlds/landstalker/docs/en_Landstalker - The Treasures of King Nole.md b/worlds/landstalker/docs/en_Landstalker - The Treasures of King Nole.md new file mode 100644 index 000000000000..90a79f8bd986 --- /dev/null +++ b/worlds/landstalker/docs/en_Landstalker - The Treasures of King Nole.md @@ -0,0 +1,60 @@ +# Landstalker: The Treasures of King Nole + +## Where is the settings page? + +The [player settings page for this game](../player-settings) contains most of the options you need to +configure and export a config file. + +## What does randomization do to this game? + +All items are shuffled while keeping a logic to make every seed completable. + +Some key items could be obtained in a very different order compared to the vanilla game, leading to very unusual situations. + +The world is made as open as possible while keeping the original locks behind the same items & triggers as vanilla +when that makes sense logic-wise. This puts the emphasis on exploration and gameplay by removing all the scenario +and story-related triggers, giving a wide open world to explore. + +## What items and locations get shuffled? + +All items and locations are shuffled. This includes **chests**, items on **ground**, in **shops**, and given by **NPCs**. + +It's also worth noting that all of these items are shuffled among all worlds, meaning every item can be sent to you +by other players. + +## What are the main differences compared to the vanilla game? + +The **Key** is now a unique item and can open several doors without being consumed, making it a standard progression item. +All key doors are gone, except three of them : + - the Mercator castle backdoor (giving access to Greenmaze sector) + - Thieves Hideout middle door (cutting the level in half) + - King Nole's Labyrinth door near entrance + +--- + +The secondary shop of Mercator requiring to do the traders sidequest in the original game is now unlocked by having +**Buyer Card** in your inventory. + +You will need as many **jewels** as specified in the settings to use the teleporter to go to Kazalt and the final dungeon. +If you find and use the **Lithograph**, it will tell you in which world are each one of your jewels. + +Each seed, there is a random dungeon which is chosen to be the "dark dungeon" where you won't see anything unless you +have the **Lantern** in your inventory. Unlike vanilla, King Nole's Labyrinth no longer has the few dark rooms the lantern +was originally intended for. + +The **Statue of Jypta** is introduced as a real item (instead of just being an intro gimmick) and gives you gold over +time while you're walking, the same way Healing Boots heal you when you walk. + + +## What do I need to know for my first seed? + +It's advised you keep Massan as your starting region for your first seed, since taking another starting region might +be significantly harder, both combat-wise and logic-wise. + +Having fully open & shuffled teleportation trees is an interesting way to play, but is discouraged for beginners +as well since it can force you to go in late-game zones with few Life Stocks. + +Overall, the default settings are good for a beginner-friendly seed, and if you don't feel too confident, you can also +lower the combat difficulty to make it more forgiving. + +*Have fun on your adventure!* diff --git a/worlds/landstalker/docs/landstalker_setup_en.md b/worlds/landstalker/docs/landstalker_setup_en.md new file mode 100644 index 000000000000..9f453c146de3 --- /dev/null +++ b/worlds/landstalker/docs/landstalker_setup_en.md @@ -0,0 +1,119 @@ +# Landstalker Setup Guide + +## Required Software + +- [Landstalker Archipelago Client](https://github.com/Dinopony/randstalker-archipelago/releases) (only available on Windows) +- A compatible emulator to run the game + - [RetroArch](https://retroarch.com?page=platforms) with the Genesis Plus GX core + - [Bizhawk 2.9.1 (x64)](https://tasvideos.org/BizHawk/ReleaseHistory) with the Genesis Plus GX core +- Your legally obtained Landstalker US ROM file (which can be acquired on [Steam](https://store.steampowered.com/app/71118/Landstalker_The_Treasures_of_King_Nole/)) + +## Installation Instructions + +- Unzip the Landstalker Archipelago Client archive into its own folder +- Put your Landstalker ROM (`LandStalker_USA.SGD` on the Steam release) inside this folder +- To launch the client, launch `randstalker_archipelago.exe` inside that folder + +Be aware that you might get antivirus warnings about the client program because one of its main features is to spy +on another process's memory (your emulator). This is something antiviruses obviously dislike, and sometimes mistake +for malicious software. + +If you're not trusting the program, you can check its [source code](https://github.com/Dinopony/randstalker-archipelago/) +or test it on a service like Virustotal. + +## Create a Config (.yaml) File + +### What is a config file and why do I need one? + +See the guide on setting up a basic YAML at the Archipelago setup +guide: [Basic Multiworld Setup Guide](/tutorial/Archipelago/setup/en) + +### Where do I get a config file? + +The [Player Settings Page](../player-settings) on the website allows you to easily configure your personal settings +and export a config file from them. + +## How-to-play + +### Connecting to the Archipelago Server + +Once the game has been created, you need to connect to the server using the Landstalker Archipelago Client. + +To do so, run `randstalker_archipelago.exe` inside the folder you created while installing the software. + +A window will open with a few settings to enter: +- **Host**: Put the server address and port in this field (e.g. `archipelago.gg:12345`) +- **Slot name**: Put the player name you specified in your YAML config file in this field. +- **Password**: If the server has a password, put it there. + +![Landstalker Archipelago Client user interface](/static/generated/docs/Landstalker%20-%20The%20Treasures%20of%20King%20Nole/ls_guide_ap.png) + +Once all those fields were filled appropriately, click on the `Connect to Archipelago` button below to try connecting to +the Archipelago server. + +If this didn't work, double-check your credentials. An error message should be displayed on the console log to the +right that might help you find the cause of the issue. + +### ROM Generation + +When you connected to the Archipelago server, the client fetched all the required data from the server to be able to +build a randomized ROM. + +You should see a window with settings to fill: +- **Input ROM file**: This is the path to your original ROM file for the game. If you are using the Steam release ROM + and placed it inside the client's folder as mentioned above, you don't need to change anything. +- **Output ROM directory**: This is where the randomized ROMs will be put. No need to change this unless you want them + to be created in a very specific folder. + +![Landstalker Archipelago Client user interface](/static/generated/docs/Landstalker%20-%20The%20Treasures%20of%20King%20Nole/ls_guide_rom.png) + +There also a few cosmetic options you can fill before clicking the `Build ROM` button which should create your +randomized seed if everything went right. + +If it didn't, double-check your `Input ROM file` and `Output ROM path`, then retry building the ROM by clicking +the same button again. + +### Connecting to the emulator + +Now that you're connected to the Archipelago server and have a randomized ROM, all we need is to get the client +connected to the emulator. This way, the client will be able to see what's happening while you play and give you in-game +the items you have received from other players. + +You should see the following window: + +![Landstalker Archipelago Client user interface](/static/generated/docs/Landstalker%20-%20The%20Treasures%20of%20King%20Nole/ls_guide_emu.png) + +As written, you have to open the newly generated ROM inside either Retroarch or Bizhawk using the Genesis Plus GX core. +Be careful to select that core, because any other core (e.g. BlastEm) won't work. + +The easiest way to do so is to: +- open the emu of your choice +- if you're using Retroarch and it's your first time, download the Genesis Plus GX core through Retroarch user interface +- click the `Show ROM file in explorer` button +- drag-and-drop the shown ROM file on the emulator window +- press Start to reach file select screen (to ensure game RAM is properly set-up) + +Then, you can click on the `Connect to emulator` button below and it should work. + +If this didn't work, try the following: +- ensure you have loaded your ROM and reached the save select screen +- ensure you are using Genesis Plus GX and not another core (e.g. BlastEm will not work) +- try launching the client in Administrator Mode (right-click on `randstalker_archipelago.exe`, then + `Run as administrator`) +- if all else fails, try using one of those specific emulator versions: + - RetroArch 1.9.0 and Genesis Plus GX 1.7.4 + - Bizhawk 2.9.1 (x64) + +### Play the game + +If all indicators are green and show "Connected," you're good to go! Play the game and enjoy the wonders of isometric +perspective. + +The client is packaged with both an **automatic item tracker** and an **automatic map tracker** for your comfort. + +If you don't know all checks in the game, don't be afraid: you can click the `Where is it?` button that will show +you a screenshot of where the location actually is. + +![Landstalker Archipelago Client user interface](/static/generated/docs/Landstalker%20-%20The%20Treasures%20of%20King%20Nole/ls_guide_client.png) + +Have fun! \ No newline at end of file diff --git a/worlds/landstalker/docs/ls_guide_ap.png b/worlds/landstalker/docs/ls_guide_ap.png new file mode 100644 index 0000000000000000000000000000000000000000..674938ce6707d4f1384a7d1771b66c4a39e5e428 GIT binary patch literal 2283 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 literal 0 HcmV?d00001 diff --git a/worlds/landstalker/docs/ls_guide_emu.png b/worlds/landstalker/docs/ls_guide_emu.png new file mode 100644 index 0000000000000000000000000000000000000000..ff9218de12bafba18009b57efe85b9003930998a GIT binary patch literal 2598 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 literal 0 HcmV?d00001 diff --git a/worlds/landstalker/docs/ls_guide_rom.png b/worlds/landstalker/docs/ls_guide_rom.png new file mode 100644 index 0000000000000000000000000000000000000000..c57554ab43d875c7ee0110990572daa4ae1e6d6b GIT binary patch literal 3951 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 literal 0 HcmV?d00001