From 54822e47681fe7614f7a0d35c818c57f819c4f44 Mon Sep 17 00:00:00 2001 From: UmedMuzl Date: Mon, 2 Feb 2026 21:07:43 -0600 Subject: [PATCH 1/7] custom locations/UT Map --- __init__.py | 155 +++++- archipelago/DK64Client.py | 101 +++- archipelago/FillSettings.py | 10 +- archipelago/Options.py | 47 +- archipelago/Regions.py | 58 ++- archipelago/Tracker.py | 916 ++++++++++++++++++++++++++++++++++++ 6 files changed, 1238 insertions(+), 49 deletions(-) create mode 100644 archipelago/Tracker.py diff --git a/__init__.py b/__init__.py index 1817ebf87..cae5a7a6e 100644 --- a/__init__.py +++ b/__init__.py @@ -184,6 +184,7 @@ def copy_dependencies(zip_path, file): from worlds.LauncherComponents import Component, SuffixIdentifier, components, Type, icon_paths import randomizer.ShuffleExits as ShuffleExits from archipelago.FillSettings import fillsettings + from archipelago import Tracker from Utils import open_filename import shutil import zlib @@ -283,8 +284,18 @@ class EnableMinimalLogic(settings.Bool): This allows hosts to disable the minimal logic option if they don't want it on their server. """ + class UTPackPath(settings.UserFilePath): + """Path to external Universal Tracker pack .zip file. + + Download the DK64 tracker pack from https://github.com/UmedMuzl/dk64pt/releases + and point this setting to the downloaded .zip file to enable map tracking in Universal Tracker. + Leave empty to disable map tracking. + """ + description = "Universal Tracker Pack Path (Optional)" + release_branch: ReleaseVersion = ReleaseVersion("master") enable_minimal_logic_dk64: EnableMinimalLogic | bool = False + ut_pack_path: typing.Union[UTPackPath, str] = UTPackPath("") class DK64Web(WebWorld): """WebWorld for DK64.""" @@ -325,6 +336,7 @@ class DK64World(World): item_name_to_id = {name: data.code for name, data in full_item_table.items()} location_name_to_id = all_locations + tracker_world: typing.ClassVar = Tracker.tracker_world def blueprint_item_group() -> str: """Item group for blueprints.""" @@ -1093,7 +1105,47 @@ def generate_early(self): self.spoiler.LocationList[DK64RLocations.FactoryDonkeyDKArcade].name = "Factory Donkey DK Arcade Round 1" self.spoiler.settings.shuffled_location_types.append(Types.ArchipelagoItem) + # Handle custom location shuffling BEFORE regions are created + # This needs to happen early so the logic system knows about the new locations + from randomizer.Lists.CustomLocations import resetCustomLocations + from randomizer.ShuffleCrowns import ShuffleCrowns + from randomizer.ShuffleCrates import ShuffleMelonCrates + from randomizer.ShufflePatches import ShufflePatches + + resetCustomLocations(self.spoiler) + + # Store custom location flags + do_crown_shuffle = self.spoiler.settings.crown_placement_rando + do_patch_shuffle = self.spoiler.settings.random_patches + do_crate_shuffle = self.spoiler.settings.random_crates + + # Temporarily disable custom locations so Generate_Spoiler doesn't run them + self.spoiler.settings.crown_placement_rando = False + self.spoiler.settings.random_patches = False + self.spoiler.settings.random_crates = False + Generate_Spoiler(self.spoiler) + + # Restore settings + self.spoiler.settings.crown_placement_rando = do_crown_shuffle + self.spoiler.settings.random_patches = do_patch_shuffle + self.spoiler.settings.random_crates = do_crate_shuffle + + # Now run custom location shuffles + if do_crown_shuffle: + crown_replacements = {} + crown_human_replacements = {} + ShuffleCrowns(self.spoiler, crown_replacements, crown_human_replacements) + self.spoiler.crown_locations = crown_replacements + self.spoiler.human_crowns = dict(sorted(crown_human_replacements.items())) + + if do_patch_shuffle: + human_patches = {} + self.spoiler.human_patches = ShufflePatches(self.spoiler, human_patches).copy() + + if do_crate_shuffle: + human_crates = {} + self.spoiler.human_crates = ShuffleMelonCrates(self.spoiler, human_crates).copy() # Store/retrieve blocker values for seed group synchronization if self.options.loading_zone_rando.value not in [0, LoadingZoneRando.option_no]: @@ -1841,6 +1893,81 @@ def get_smaller_shops_data(self) -> dict: return smaller_shops_data + def get_custom_location_names(self) -> dict: + """Get the mapping of location IDs to custom location data. + + Returns a dictionary mapping location ID to a dict containing: + - 'name': the actual custom name assigned during shuffle + - 'flag': the flag ID used for checking completion in-game + Only includes locations whose names differ from the base location name. + """ + from randomizer.Enums.Locations import Locations as DK64RLocations + from randomizer.Lists.Location import LocationListOriginal as VanillaLocationList + from archipelago.Regions import BASE_ID + + custom_locations = {} + + # Get all custom location IDs + # Battle Arenas are not in a contiguous range, so list them explicitly + battle_arena_locations = [ + DK64RLocations.IslesBattleArena1, + DK64RLocations.IslesBattleArena2, + DK64RLocations.JapesBattleArena, + DK64RLocations.AztecBattleArena, + DK64RLocations.FactoryBattleArena, + DK64RLocations.GalleonBattleArena, + DK64RLocations.ForestBattleArena, + DK64RLocations.CavesBattleArena, + DK64RLocations.CastleBattleArena, + DK64RLocations.HelmBattleArena, + ] + dirt_range = range(DK64RLocations.RainbowCoin_Location00, DK64RLocations.RainbowCoin_Location15 + 1) + crate_range = range(DK64RLocations.MelonCrate_Location00, DK64RLocations.MelonCrate_Location12 + 1) + + custom_location_ids = set(battle_arena_locations) | set(dirt_range) | set(crate_range) + + print(f"[DK64 get_custom_location_names] Checking {len(custom_location_ids)} potential custom locations") + + # Build a mapping from enum to index in LocationListOriginal + enum_to_index = {location: index for index, location in enumerate(VanillaLocationList)} + + for location_enum in custom_location_ids: + if location_enum in self.spoiler.LocationList: + location_obj = self.spoiler.LocationList[location_enum] + # Get the vanilla name to compare + vanilla_name = VanillaLocationList[location_enum].name if location_enum in VanillaLocationList else None + + # Debug: Print info about Battle Arena locations + if location_enum in battle_arena_locations: + print(f"[DK64] Battle Arena enum {location_enum}: name='{location_obj.name}', vanilla='{vanilla_name}'") + + # Include all custom locations, even if names haven't changed + # This is necessary because flags can be shuffled even if names stay the same + if location_obj.name: + # Calculate the AP location ID using the INDEX, not the enum value + index = enum_to_index.get(location_enum) + if index is None: + print(f"[DK64] WARNING: Could not find index for location enum {location_enum}") + continue + location_id = BASE_ID + index + # Get the flag ID from the location's default_mapid_data + flag_id = None + if location_obj.default_mapid_data and len(location_obj.default_mapid_data) > 0: + flag_id = location_obj.default_mapid_data[0].flag + custom_locations[location_id] = { + 'name': location_obj.name, + 'flag': flag_id + } + # Debug: print first few + if len(custom_locations) <= 3: + print(f" Found custom location: {location_obj.name} (ID: {location_id}, Enum: {location_enum}, Index: {index}, Flag: {flag_id}, was: {vanilla_name})") + else: + if location_enum in battle_arena_locations: + print(f"[DK64] WARNING: Battle Arena enum {location_enum} NOT in spoiler.LocationList!") + + print(f"[DK64 get_custom_location_names] Found {len(custom_locations)} custom locations total") + return custom_locations + def fill_slot_data(self) -> dict: """Fill the slot data.""" # If hints are enabled, wait for hint compilation to complete @@ -1963,14 +2090,8 @@ def fill_slot_data(self) -> dict: }, "StartingRegion": ( { - "region": ( - self.spoiler.settings.starting_region["region"].name - if hasattr(self.spoiler.settings.starting_region["region"], "name") - else str(self.spoiler.settings.starting_region["region"]) - ), - "map": ( - self.spoiler.settings.starting_region["map"].name if hasattr(self.spoiler.settings.starting_region["map"], "name") else str(self.spoiler.settings.starting_region["map"]) - ), + "region": self.spoiler.settings.starting_region["region"].name if hasattr(self.spoiler.settings.starting_region["region"], "name") else str(self.spoiler.settings.starting_region["region"]), + "map": self.spoiler.settings.starting_region["map"].name if hasattr(self.spoiler.settings.starting_region["map"], "name") else str(self.spoiler.settings.starting_region["map"]), "exit": self.spoiler.settings.starting_region["exit"], "region_name": self.spoiler.settings.starting_region["region_name"], "exit_name": self.spoiler.settings.starting_region["exit_name"], @@ -1978,8 +2099,24 @@ def fill_slot_data(self) -> dict: if hasattr(self.spoiler.settings, "starting_region") and self.spoiler.settings.starting_region else {} ), - "DKPortalLocations": (self.spoiler.human_entry_doors if hasattr(self.spoiler, "human_entry_doors") and self.spoiler.human_entry_doors else {}), + "DKPortalLocations": ( + self.spoiler.human_entry_doors + if hasattr(self.spoiler, "human_entry_doors") and self.spoiler.human_entry_doors + else {} + ), + "CustomLocationNames": self.get_custom_location_names(), } + + # Debug logging for custom locations + custom_locs = slot_data.get("CustomLocationNames", {}) + if custom_locs: + print(f"[DK64 Generation] Sending {len(custom_locs)} custom locations in slot_data") + for i, (loc_id, data) in enumerate(list(custom_locs.items())[:3]): + if isinstance(data, dict): + print(f" Location {loc_id}: {data.get('name')} (flag: {data.get('flag')})") + else: + print(f" Location {loc_id}: {data}") + return slot_data def write_spoiler(self, spoiler_handle: typing.TextIO): diff --git a/archipelago/DK64Client.py b/archipelago/DK64Client.py index 211102d04..c38c90905 100644 --- a/archipelago/DK64Client.py +++ b/archipelago/DK64Client.py @@ -178,6 +178,9 @@ class DK64Client: item_names = None players = None _purchase_cache = {} + custom_check_id_to_name = {} + custom_check_id_to_flag = {} + custom_flag_to_check_id = {} # Reverse mapping: flag_id -> location_id ENABLE_DEATHLINK = False ENABLE_RINGLINK = False ENABLE_TAGLINK = False @@ -696,14 +699,25 @@ def getCheckStatus(self, check_type, flag_index=None, shop_index=None, level_ind async def readChecks(self, cb): """Run checks in parallel using asyncio.""" new_checks = [] - checks_to_read = self.remaining_checks + checks_to_read = self.remaining_checks.copy() for id in checks_to_read: - name = check_id_to_name.get(id) - # Try to get the check via location_name_to_flag - check = location_name_to_flag.get(name) + # Get location name (prefer custom name if available) + name = self.custom_check_id_to_name.get(id, check_id_to_name.get(id)) + + # Determine which flag to check for this location + check = None + + # For custom locations (crowns, dirt, crates), ONLY use the custom flag + # Do not fall back to location_name_to_flag as that would use vanilla flags + if id in self.custom_check_id_to_flag: + check = self.custom_check_id_to_flag.get(id) + else: + # For non-custom locations, use the vanilla flag mapping + check = location_name_to_flag.get(name) + if check: - # Assuming we did find it in location_name_to_flag + # Check if this flag is set in memory check_status = self.getCheckStatus("location", check) if check_status: self.remaining_checks.remove(id) @@ -1076,7 +1090,8 @@ def reset_checks(self): # Debug logging for shared shops shared_shop_ids = set() for location_id in actual_checks: - location_name = check_id_to_name.get(location_id, "") + # Use custom name if available, otherwise fall back to check_id_to_name + location_name = self.custom_check_id_to_name.get(location_id, check_id_to_name.get(location_id, "")) if "Shared" in location_name: shared_shop_ids.add(location_id) else: @@ -1086,6 +1101,7 @@ def reset_checks(self): self.client.pending_checks = [] self.found_checks = [] self.client.flag_lookup = None + self.custom_flag_to_check_id = {} self.handled_scouts = [] self.create_hints_params = [] @@ -1094,6 +1110,8 @@ def __init__(self, server_address: typing.Optional[str], password: typing.Option self.client = DK64Client() self.client.game = self.game.upper() self.slot_data = {} + self.custom_check_id_to_name = {} + self.custom_check_id_to_flag = {} self.reset_checks() super().__init__(server_address, password) @@ -1137,6 +1155,70 @@ async def send_checks(self): had_invalid_slot_data: typing.Optional[bool] = None + def update_custom_location_names(self): + """Update the check_id_to_name dictionary with custom location names from slot_data.""" + custom_location_data = self.slot_data.get("CustomLocationNames", {}) + logger.info(f"CustomLocationNames in slot_data: {len(custom_location_data)} entries") + if custom_location_data: + # Convert string keys back to integers and extract both name and flag + self.custom_check_id_to_name = {} + self.custom_check_id_to_flag = {} + self.custom_flag_to_check_id = {} # Reverse mapping for flag -> location ID + for id_str, data in custom_location_data.items(): + loc_id = int(id_str) + if isinstance(data, dict): + self.custom_check_id_to_name[loc_id] = data.get('name') + if data.get('flag') is not None: + flag_id = data.get('flag') + self.custom_check_id_to_flag[loc_id] = flag_id + # Build reverse mapping: flag_id -> location_id + self.custom_flag_to_check_id[flag_id] = loc_id + else: + # Backwards compatibility: if data is just a string (old format) + self.custom_check_id_to_name[loc_id] = data + + # Also update the client's dictionaries + self.client.custom_check_id_to_name = self.custom_check_id_to_name + self.client.custom_check_id_to_flag = self.custom_check_id_to_flag + self.client.custom_flag_to_check_id = self.custom_flag_to_check_id + + # Update the location_names lookup used by Archipelago's notification system + # We need to inject custom names so they take priority over base names + if hasattr(self, 'location_names') and self.location_names: + logger.info(f"Updating location_names with {len(self.custom_check_id_to_name)} custom location names") + try: + # Get the game's location store ChainMap + if self.game in self.location_names._game_store: + game_store = self.location_names._game_store[self.game] + + # Create our custom names dict + custom_names_dict = {loc_id: name for loc_id, name in self.custom_check_id_to_name.items() if name} + + # Use new_child() to prepend our custom names to the existing ChainMap + # This modifies the ChainMap in place and ensures any existing references see the update + updated_chain = game_store.new_child(custom_names_dict) + self.location_names._game_store[self.game] = updated_chain + + logger.info(f"Successfully injected {len(custom_names_dict)} custom location names") + + # Verify a few + for loc_id in list(custom_names_dict.keys())[:3]: + verified_name = self.location_names.lookup_in_game(loc_id, self.game) + logger.info(f" Verified location {loc_id}: '{verified_name}'") + else: + logger.warning(f"Game '{self.game}' not found in location_names._game_store") + except Exception as e: + logger.error(f"Failed to update location_names: {e}", exc_info=True) + else: + logger.warning(f"location_names not available for update") + + logger.info(f"Loaded {len(self.custom_check_id_to_name)} custom location names from slot_data") + logger.info(f"Built reverse mapping with {len(self.custom_flag_to_check_id)} flag->location_id entries") + # Debug: print first few custom locations + for i, (loc_id, name) in enumerate(list(self.custom_check_id_to_name.items())[:3]): + flag = self.custom_check_id_to_flag.get(loc_id) + logger.info(f" Custom location {loc_id}: {name} (flag: {flag})") + def event_invalid_slot(self): """Handle an invalid slot event.""" # The next time we try to connect, reset the game loop for new auth @@ -1187,6 +1269,7 @@ def on_package(self, cmd: str, args: dict): if cmd == "Connected": self.game = self.slot_info[self.slot].game self.slot_data = args.get("slot_data", {}) + self.update_custom_location_names() self.setup_hint_locations() if self.slot_data.get("Version"): ap_version = get_ap_version() @@ -1248,7 +1331,8 @@ def on_package(self, cmd: str, args: dict): # If the location is in the list, remove it player_name = self.player_names.get(location.player) location_id = location.location - item_name = self.item_names.lookup_in_game(location.item, self.slot_info[location.player].game) + # Always use DK64's game context to get the correct item name for items in DK64 locations + item_name = self.item_names.lookup_in_game(location.item, self.game) self.client.locations_scouted[location_id] = {"player": player_name, "item_name": item_name} if isinstance(args, dict) and isinstance(args.get("data", {}), dict): source_name = args.get("data", {}).get("source", None) @@ -1663,7 +1747,8 @@ def on_item_get(dk64_checks): """Handle an item get.""" built_checks_list = [] for check in dk64_checks: - check_name = check_id_to_name.get(check) + # Use custom name if available, otherwise fall back to check_id_to_name + check_name = self.custom_check_id_to_name.get(check, check_id_to_name.get(check)) if check_name: built_checks_list.append(check) continue diff --git a/archipelago/FillSettings.py b/archipelago/FillSettings.py index ee9d9f63b..e65e08e9c 100644 --- a/archipelago/FillSettings.py +++ b/archipelago/FillSettings.py @@ -99,7 +99,6 @@ def get_default_settings() -> dict: "boss_location_rando": True, "cannons_require_blast": True, "cb_medal_behavior_new": CBRequirement.pre_selected, - "cb_rando_enabled": False, "chunky_phase_slam_req": SlamRequirement.green, "coin_door_item": HelmDoorItem.opened, "coin_door_item_count": 1, @@ -107,7 +106,6 @@ def get_default_settings() -> dict: "crown_door_item": HelmDoorItem.opened, "crown_door_item_count": 1, "crown_enemy_difficulty": CrownEnemyDifficulty.easy, - "crown_placement_rando": False, "damage_amount": DamageAmount.default, "decouple_item_rando": False, "dim_solved_hints": False, @@ -268,9 +266,7 @@ def get_default_settings() -> dict: "progressive_hint_item": ProgressiveHintItem.off, "puzzle_rando_difficulty": PuzzleRando.medium, "race_coin_rando": False, - "random_crates": False, "random_fairies": False, - "random_patches": False, "random_starting_region": False, "random_starting_region_new": RandomStartingRegion.off, "randomize_enemy_sizes": False, @@ -364,6 +360,12 @@ def apply_archipelago_settings(settings_dict: dict, options, multiworld) -> None settings_dict["galleon_water"] = GalleonWaterSetting.vanilla settings_dict["no_consumable_upgrades"] = options.remove_bait_potions.value + # Custom location settings + settings_dict["crown_placement_rando"] = options.crown_placement_rando.value + settings_dict["random_crates"] = options.random_crates.value + settings_dict["random_patches"] = options.random_patches.value + settings_dict["cb_rando_enabled"] = options.cb_rando_enabled.value + def apply_blocker_settings(settings_dict: dict, options) -> None: """Apply level blocker settings.""" diff --git a/archipelago/Options.py b/archipelago/Options.py index 9a1db0500..cdc9b3fb0 100644 --- a/archipelago/Options.py +++ b/archipelago/Options.py @@ -179,7 +179,7 @@ class StartingMoveCount(Range): class KroolShuffle(Choice): """Whether or not K. Rool can be fightable in T&S Bosses and vice versa. - + "off": K. Rool can only appear in the final fight. "krool_only": K. Rool can appear in T&S bosses, but T&S can't appear in the final fight. "full_shuffle": K. Rool and T&S bosses can be shuffled between eachother. @@ -193,7 +193,6 @@ class KroolShuffle(Choice): default = 0 - class AllowedBosses(OptionList): """Determines which bosses are in the pool. If not enough bosses are selected, it will fill the pool with duplicate bosses""" @@ -202,7 +201,6 @@ class AllowedBosses(OptionList): valid_keys: {"Armydillo 1", "Dogadon 1", "Mad Jack", "Pufftoss", "Dogadon 2", "Armydillo 2", "Kutout", "DK phase", "Diddy Phase", "Lanky Phase", "Tiny Phase", "Chunky Phase"} default = ["Armydillo 1", "Dogadon 1", "Mad Jack", "Pufftoss", "Dogadon 2", "Armydillo 2", "Kutout", "DK phase", "Diddy Phase", "Lanky Phase", "Tiny Phase", "Chunky Phase"] - class TrapFillPercentage(Range): """Replace a percentage of junk items in the item pool with random traps.""" @@ -413,6 +411,34 @@ class SwitchSanity(Choice): default = 0 +class CrownPlacementRando(Toggle): + """Randomizes the locations of Battle Arena crown pads to alternate positions throughout the levels.""" + + display_name = "Crown Placement Randomization" + + +class RandomCrates(Toggle): + """Randomizes the locations of Melon Crates to alternate positions throughout the levels.""" + + display_name = "Random Melon Crates" + + +class RandomPatches(Toggle): + """Randomizes the locations of Dirt Patches (Rainbow Coins) to alternate positions throughout the levels.""" + + display_name = "Random Dirt Patches" + + +## TODO: Figure this out +# class CBRando(Toggle): +# """Randomizes the locations of Colored Bananas throughout the levels. + +# This does NOT make individual bananas checks - they remain collectibles that count toward medals. +# """ + +# display_name = "Colored Banana Randomization" + + class LogicType(Choice): """Determines what type of logic is needed to beat the seed. @@ -1425,7 +1451,7 @@ class DKPortalLocationRando(Choice): """Randomize the locations of DK Portals within levels. DK Portals are the exits that return you from a level to its lobby. - + - off: DK Portals remain in their vanilla locations - main_only: DK Portals can only appear in main level areas (not bonus barrels, buildings, etc.) - all: DK Portals can appear anywhere in the level @@ -1468,6 +1494,10 @@ class DK64Options(PerGameCommonOptions): level_blockers: LevelBlockers open_lobbies: OpenLobbies switchsanity: SwitchSanity + crown_placement_rando: CrownPlacementRando + random_crates: RandomCrates + random_patches: RandomPatches + # cb_rando_enabled: CBRando climbing_shuffle: ClimbingShuffle starting_kong_count: StartingKongCount starting_move_count: StartingMoveCount @@ -1603,6 +1633,15 @@ class DK64Options(PerGameCommonOptions): DKPortalLocationRando, ], ), + OptionGroup( + "Custom Locations", + [ + CrownPlacementRando, + RandomCrates, + RandomPatches, + # CBRando, + ], + ), OptionGroup( "Logic", [ diff --git a/archipelago/Regions.py b/archipelago/Regions.py index 20cd18394..e857e5493 100644 --- a/archipelago/Regions.py +++ b/archipelago/Regions.py @@ -111,6 +111,14 @@ def create_regions(multiworld: MultiWorld, player: int, spoiler: Spoiler, option # okay okay OKAY you get a logicVarHolder object for JUST THIS ONCE. Codes these days... logic_holder = LogicVarHolder(spoiler, player) + # Build location table from spoiler's LocationList (which may have custom locations) + all_locations_dynamic = { + spoiler.LocationList[location].name: (BASE_ID + index) + for index, location in enumerate(DK64RLocation.LocationListOriginal) + if spoiler.LocationList[location].type != Types.EnemyPhoto + } + all_locations_dynamic.update({"Victory": 0x00}) # Temp for generating goal location + # Pick random 10 shops to make shared # Only if shared shops are enabled in settings if options.enable_shared_shops.value: @@ -126,8 +134,8 @@ def create_regions(multiworld: MultiWorld, player: int, spoiler: Spoiler, option shared_shop_vendors = set() # Pre-process to identify which vendor/level combinations will have shared shops - for region_id in all_logic_regions: - region_obj = all_logic_regions[region_id] + for region_id in logic_holder.spoiler.RegionList: + region_obj = logic_holder.spoiler.RegionList[region_id] location_logics = [loc for loc in region_obj.locations if (not loc.isAuxiliaryLocation) or region_id.name == "FactoryBaboonBlast"] for location_logic in location_logics: @@ -150,8 +158,8 @@ def create_regions(multiworld: MultiWorld, player: int, spoiler: Spoiler, option # for location_name, location_id in all_locations.items(): # print(f"{location_name}: {location_id}") - for region_id in all_logic_regions: - region_obj = all_logic_regions[region_id] + for region_id in logic_holder.spoiler.RegionList: + region_obj = logic_holder.spoiler.RegionList[region_id] # Filtering out auxiliary locations is detrimental to glitch logic, but is necessary to ensure each location placed exactly once location_logics = [loc for loc in region_obj.locations if (not loc.isAuxiliaryLocation) or region_id.name == "FactoryBaboonBlast"] # V1 LIMITATION: Helm must be skip_start @@ -171,16 +179,17 @@ def create_regions(multiworld: MultiWorld, player: int, spoiler: Spoiler, option if (region_id == Regions.HideoutHelmEntry and spoiler.settings.helm_chunky) or (region_id == Regions.HideoutHelmChunkyRoom and not spoiler.settings.helm_chunky): location_logics = [loc for loc in location_logics if loc.id not in (Locations.HelmChunky1, Locations.HelmChunky2)] collectibles = [] - if region_id in all_collectible_regions.keys(): + # Use spoiler.CollectibleRegions which reflects CB randomization if enabled + if region_id in logic_holder.spoiler.CollectibleRegions.keys(): collectible_types = [Collectibles.bunch, Collectibles.banana, Collectibles.balloon] collectible_types.append(Collectibles.coin) - collectibles = [col for col in all_collectible_regions[region_id] if col.type in collectible_types] + collectibles = [col for col in logic_holder.spoiler.CollectibleRegions[region_id] if col.type in collectible_types] events = [event for event in region_obj.events] # if region_obj.level == Levels.Shops: - # multiworld.regions.append(create_shop_region(multiworld, player, region_id.name, region_obj, location_logics, spoiler.settings)) + # multiworld.regions.append(create_shop_region(multiworld, player, region_id.name, region_obj, location_logics, spoiler.settings, all_locations_dynamic)) # else: - multiworld.regions.append(create_region(multiworld, player, region_id.name, region_obj.level, location_logics, collectibles, events, logic_holder)) + multiworld.regions.append(create_region(multiworld, player, region_id.name, region_obj.level, location_logics, collectibles, events, logic_holder, all_locations_dynamic)) def create_region( @@ -192,6 +201,7 @@ def create_region( collectibles: typing.List[Collectible], events: typing.List[Event], logic_holder: LogicVarHolder, + all_locations_dynamic: typing.Dict[str, int], ) -> Region: """Create a region for the given player's world.""" new_region = Region(region_name, player, multiworld) @@ -239,7 +249,7 @@ def create_region( # Skip locations marked as inaccessible by smaller shops if hasattr(location_obj, "smallerShopsInaccessible") and location_obj.smallerShopsInaccessible and logic_holder.settings.smaller_shops: continue - loc_id = all_locations.get(location_obj.name, 0) + loc_id = all_locations_dynamic.get(location_obj.name, 0) # Universal Tracker: don't add this location if it has no item if hasattr(multiworld, "generation_is_fake"): if hasattr(multiworld, "re_gen_passthrough"): @@ -503,7 +513,7 @@ def create_region( # CURRENTLY UNUSED - for some reason some Lanky shops are inaccessible?? -def create_shop_region(multiworld: MultiWorld, player: int, region_name: str, region_obj: DK64Region, location_logics: typing.List[LocationLogic], settings: Settings) -> Region: +def create_shop_region(multiworld: MultiWorld, player: int, region_name: str, region_obj: DK64Region, location_logics: typing.List[LocationLogic], settings: Settings, all_locations_dynamic: typing.Dict[str, int]) -> Region: """Create a region for the given player's world.""" # Shop regions have relatively straightforward logic that can be streamlined for performance purposes new_region = Region(region_name, player, multiworld) @@ -513,14 +523,14 @@ def create_shop_region(multiworld: MultiWorld, player: int, region_name: str, re for kong in range(5): blueprint_obj = DK64RItem.ItemList[Items.DonkeyBlueprint + kong] location_name = "Turn In " + blueprint_obj.name - loc_id = all_locations.get(location_name, 0) + loc_id = all_locations_dynamic.get(location_name, 0) location = DK64Location(player, location_name, loc_id, new_region) set_rule(location, lambda state, blueprint_name=blueprint_obj.name: state.has(blueprint_name, player)) location.place_locked_item(DK64Item(blueprint_obj.name, ItemClassification.progression_skip_balancing, None, player)) new_region.locations.append(location) # The one special child here is Cranky Generic, home of Jetpac, the only shop location with any relevant logic elif region_name == "Cranky Generic": - location = DK64Location(player, "Jetpac", all_locations.get("Jetpac", 0), new_region) + location = DK64Location(player, "Jetpac", all_locations_dynamic.get("Jetpac", 0), new_region) set_rule(location, lambda state, player=player, location_logic=location_logics[0]: hasDK64RLocation(state, player, location_logic)) new_region.locations.append(location) settings.location_pool_size += 1 @@ -530,7 +540,7 @@ def create_shop_region(multiworld: MultiWorld, player: int, region_name: str, re location_obj = DK64RLocation.LocationListOriginal[location_logic.id] if location_obj.kong == Kongs.any: continue # We need to eliminate shared shop locations so shops don't have both a shared item and Kong items - loc_id = all_locations.get(location_obj.name, 0) + loc_id = all_locations_dynamic.get(location_obj.name, 0) location = DK64Location(player, location_obj.name, loc_id, new_region) required_kong_name = location_obj.kong.name.title() set_rule(location, lambda state, required_kong_name=required_kong_name: state.has(required_kong_name, player)) @@ -620,7 +630,7 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): # 1. Random starting region: modifies GameStart's exits to point to starting region # 2. DK Portal location rando: modifies entry handler exits to point to randomized portal locations if spoiler: - if region_id == Regions.GameStart and hasattr(settings, "starting_region") and settings.starting_region: + if region_id == Regions.GameStart and hasattr(settings, 'starting_region') and settings.starting_region: region_obj = spoiler.RegionList[Regions.GameStart] elif settings.dk_portal_location_rando_v2 != DKPortalRando.off: # Entry handler regions have their "exit level" transition (exit[1]) modified by DK portal rando @@ -635,7 +645,7 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): } if region_id in entry_handler_regions: region_obj = spoiler.RegionList[region_id] - + for exit in region_obj.exits: destination_name = exit.dest.name @@ -713,10 +723,10 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): if spoiler and settings.starting_region: starting_region_id = settings.starting_region.get("region") starting_region_obj = all_logic_regions.get(starting_region_id) - + if starting_region_obj: starting_level = starting_region_obj.level - + # Map each level to its exit transition level_exit_transitions = { Levels.JungleJapes: Transitions.JapesToIsles, @@ -727,12 +737,12 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): Levels.CrystalCaves: Transitions.CavesToIsles, Levels.CreepyCastle: Transitions.CastleToIsles, } - + # Only create exit level connection for non-Isles levels if starting_level in level_exit_transitions: exit_transition_id = level_exit_transitions[starting_level] - starting_region_name = starting_region_id.name if hasattr(starting_region_id, "name") else str(starting_region_id) - + starting_region_name = starting_region_id.name if hasattr(starting_region_id, 'name') else str(starting_region_id) + # Find the exit transition in the level's entry handler region # Entry handlers have the "exit level" transition defined in their exits level_to_entry_handler = { @@ -744,11 +754,11 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): Levels.CrystalCaves: Regions.CrystalCavesEntryHandler, Levels.CreepyCastle: Regions.CreepyCastleEntryHandler, } - + if starting_level in level_to_entry_handler: entry_handler_region = level_to_entry_handler[starting_level] entry_handler_obj = all_logic_regions.get(entry_handler_region) - + if entry_handler_obj: # Find the exit transition in the entry handler's exits exit_transition = None @@ -756,7 +766,7 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): if exit.exitShuffleId == exit_transition_id: exit_transition = exit break - + # Create connection using the exit transition's logic if exit_transition: target_region_name = exit_transition.dest.name @@ -766,7 +776,7 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): starting_region_name, target_region_name, lambda state, player=world.player, exit=exit_transition: hasDK64RTransition(state, player, exit), - "Exit Level from spawn: " + starting_region_name, + "Exit Level from spawn: " + starting_region_name ) # For tracker regeneration with LZR, also handle deathwarps and exit level connections diff --git a/archipelago/Tracker.py b/archipelago/Tracker.py new file mode 100644 index 000000000..49cad94fc --- /dev/null +++ b/archipelago/Tracker.py @@ -0,0 +1,916 @@ +"""Universal Tracker integration for DK64.""" + +from typing import Any + + +def dk64_map_to_tab_index(data: Any) -> int: + # TODO: Make a map mapping for UT + pass + + +# PopTracker section name to Archipelago location ID mapping +# Format: "Parent/Section Name": location_id +# Auto-generated from location_mapping.lua (837 locations total) +poptracker_name_mapping = { + "Medals/Aztec DK Medal": 14041209, + "Medals/Aztec Diddy Medal": 14041210, + "Medals/Aztec Lanky Medal": 14041211, + "Medals/Aztec Tiny Medal": 14041212, + "Medals/Aztec Chunky Medal": 14041213, + "Medals/Aztec DK Half-Medal": 14042334, + "Medals/Aztec Diddy Half-Medal": 14042335, + "Medals/Aztec Lanky Half-Medal": 14042336, + "Medals/Aztec Tiny Half-Medal": 14042337, + "Medals/Aztec Chunky Half-Medal": 14042338, + "Medals/Boss": 14041244, + "Aztec Chunky Vases/Golden Banana": 14041215, + "Aztec Kasplat: Behind DK Stone Door/Kasplat": 14041216, + "Aztec DK Free Llama Blast/Golden Banana": 14041214, + "Aztec Kasplat: On Tiny Temple/Kasplat": 14041217, + "Aztec Dirt: Oasis/Rainbow Coin": 14041679, + "Aztec Chunky Klaptrap Room/Golden Banana": 14041219, + "Aztec Tiny Klaptrap Room/Golden Banana": 14041218, + "Aztec Lanky Vulture Shooting/Golden Banana": 14041222, + "Aztec Battle Arena (Tiny Temple: Vulture Room)/Crown": 14041223, + "Tiny's Cage/Tiny Kong's Cage": 14041220, + "Tiny's Cage/Aztec Free Tiny Item": 14041221, + "Aztec Chunky Giant Caged Barrel/Golden Banana": 14041227, + "Aztec Kasplat: Hunky Chunky Barrel/Kasplat": 14041228, + "Aztec Diddy Ram Gongs/Golden Banana": 14041225, + "Aztec Diddy Vulture Race/Golden Banana": 14041226, + "Aztec Crate: On Llama Temple/Crate": 14041695, + "Aztec Crate: Near Gong Tower/Crate": 14041696, + "Aztec DK Sealed Quicksand Tunnel Barrel/Golden Banana": 14041224, + "5 Door Temple/Aztec DK 5DT": 14041229, + "5 Door Temple/Aztec Diddy 5DT": 14041230, + "5 Door Temple/Aztec Lanky 5DT": 14041231, + "5 Door Temple/Aztec Tiny 5DT": 14041232, + "5 Door Temple/Aztec Fairy (Inside Tiny 5DT)": 14041233, + "5 Door Temple/Aztec Chunky 5DT": 14041234, + "5 Door Temple/Aztec Kasplat: Chunky 5DT": 14041235, + "5 Door Temple/Aztec Dirt: Chunky 5DT": 14041674, + "Aztec Tiny Beetle Race/Golden Banana": 14041236, + "Lanky's Cage/Lanky Kong's Cage": 14041237, + "Lanky's Cage/Aztec Free Lanky Item": 14041238, + "Aztec Lanky Llama Temple Barrel/Golden Banana": 14041239, + "Aztec Fairy (Llama Temple)/Fairy": 14041241, + "Aztec Crate: Llama Temple/Crate": 14041691, + "Aztec Lanky Matching Game/Golden Banana": 14041240, + "Aztec Tiny Llama Temple Lava Pedestals/Golden Banana": 14041242, + "Aztec Kasplat: Llama Temple Lava/Kasplat": 14041243, + "Medals/Castle DK Medal": 14041389, + "Medals/Castle Diddy Medal": 14041390, + "Medals/Castle Lanky Medal": 14041391, + "Medals/Castle Tiny Medal": 14041392, + "Medals/Castle Chunky Medal": 14041393, + "Medals/Castle DK Half-Medal": 14042359, + "Medals/Castle Diddy Half-Medal": 14042360, + "Medals/Castle Lanky Half-Medal": 14042361, + "Medals/Castle Tiny Half-Medal": 14042362, + "Medals/Castle Chunky Half-Medal": 14042363, + "Medals/Boss": 14041422, + "Castle Diddy Above Castle/Golden Banana": 14041394, + "Castle Kasplat: Near Upper Warp 2/Kasplat": 14041395, + "Castle Dirt: Top Floor/Rainbow Coin": 14041684, + "Castle Kasplat: On a Lone Platform/Kasplat": 14041396, + "Inside the Tree/Castle DK Tree Sniping": 14041397, + "Inside the Tree/Castle Kasplat: Inside the Tree": 14041399, + "Inside the Tree/Castle Fairy (Tree Sniping Room)": 14041400, + "Inside the Tree/Castle Chunky Tree Sniping Barrel": 14041398, + "Castle DK Library/Golden Banana": 14041401, + "Castle Diddy Ballroom/Golden Banana": 14041402, + "Castle Fairy (Near Car Race)/Fairy": 14041403, + "Castle Tiny Car Race/Golden Banana": 14041404, + "Castle Lanky Tower/Golden Banana": 14041405, + "Greenhouse/Castle Lanky Greenhouse": 14041406, + "Greenhouse/Castle Battle Arena (Greenhouse Center)": 14041407, + "Castle Tiny Trashcan/Golden Banana": 14041408, + "Castle Chunky Shed/Golden Banana": 14041409, + "Castle Chunky Museum/Golden Banana": 14041410, + "Castle Kasplat: Lower Cave Center/Kasplat": 14041411, + "Castle Crate: Behind Mausoleum Entrance/Crate": 14041701, + "Castle Diddy Crypt/Golden Banana": 14041412, + "Castle Chunky Crypt/Golden Banana": 14041413, + "Castle DK Minecart/Golden Banana": 14041414, + "Mausoleum/Castle Lanky Mausoleum": 14041415, + "Mausoleum/Castle Tiny Mausoleum": 14041416, + "Castle Tiny Over Chasm/Golden Banana": 14041417, + "Castle Kasplat: Near Candy's/Kasplat": 14041418, + "Castle DK Dungeon/Golden Banana": 14041419, + "Castle Diddy Dungeon/Golden Banana": 14041420, + "Castle Lanky Dungeon/Golden Banana": 14041421, + "Medals/Caves DK Medal": 14041355, + "Medals/Caves Diddy Medal": 14041356, + "Medals/Caves Lanky Medal": 14041357, + "Medals/Caves Tiny Medal": 14041358, + "Medals/Caves Chunky Medal": 14041359, + "Medals/Caves DK Half-Medal": 14042354, + "Medals/Caves Diddy Half-Medal": 14042355, + "Medals/Caves Lanky Half-Medal": 14042356, + "Medals/Caves Tiny Half-Medal": 14042357, + "Medals/Caves Chunky Half-Medal": 14042358, + "Medals/Boss": 14041388, + "Caves Diddy Jetpack Barrel/Golden Banana": 14041361, + "Caves Kasplat: Near Ice Castle/Kasplat": 14041365, + "Caves Chunky Gorilla Gone/Golden Banana": 14041364, + "Caves Kasplat: Mini Room by Funky/Kasplat": 14041366, + "Caves Tiny Mini Cave Barrel/Golden Banana": 14041362, + "Caves Kasplat: On the Pillar/Kasplat": 14041367, + "Caves DK Baboon Blast/Golden Banana": 14041360, + "Caves Lanky Beetle Race/Golden Banana": 14041369, + "Caves Lanky Ice Castle Slam Challenge/Golden Banana": 14041370, + "Caves Tiny Monkeyport Igloo/Golden Banana": 14041363, + "Caves Chunky Transparent Igloo/Golden Banana": 14041371, + "Caves Kasplat: On 5-Door Igloo/Kasplat": 14041372, + "Caves Dirt: Giant Kosha/Rainbow Coin": 14041683, + "Caves DK 5 Door Igloo/Golden Banana": 14041373, + "Caves Diddy 5 Door Igloo/Golden Banana": 14041374, + "Caves Lanky 5 Door Igloo/Golden Banana": 14041375, + "Caves Tiny 5 Door Igloo/Golden Banana": 14041376, + "Caves Tiny 5 Door Igloo/Fairy": 14041377, + "Caves Chunky 5 Door Igloo/Golden Banana": 14041378, + "Caves Kasplat: By the Far Warp 2/Kasplat": 14041368, + "Rotating Cabin/Caves DK Rotating Cabin": 14041379, + "Rotating Cabin/Caves Battle Arena": 14041380, + "Caves DK 5 Door Cabin/Golden Banana": 14041381, + "Caves Diddy 5 Door Cabin Lower/Golden Banana": 14041382, + "Caves Diddy 5 Door Cabin Upper/Golden Banana": 14041383, + "Caves Diddy 5 Door Cabin Upper/Fairy": 14041384, + "Caves Lanky Sprint Cabin/Golden Banana": 14041385, + "Caves Tiny 5 Door Cabin/Golden Banana": 14041386, + "Caves Chunky 5 Door Cabin/Golden Banana": 14041387, + "Isles Dirt: Training Grounds Rear Tunnel/Rainbow Coin": 14041686, + "Isles Dirt: Banana Hoard/Rainbow Coin": 14041687, + "Japes Lobby Entrance/Golden Banana": 14041140, + "Chunky Pineapple Cage/Golden Banana": 14041144, + "Tiny Feather Cage/Golden Banana": 14041141, + "Chunky Pound the X/Golden Banana": 14041146, + "Isles Fairy (Small Island)/Fairy": 14041147, + "Isles Dirt: Under Caves Lobby/Rainbow Coin": 14041677, + "Isles Chunky Triangle Pad/Golden Banana": 14041145, + "K. Lumsy Prison/Isles Lanky Sprint Cage": 14041149, + "K. Lumsy Prison/Isles Dirt: Back of Prison": 14041685, + "Banana Fairy Island/The Banana Fairy's Gift": 14041150, + "Banana Fairy Island/Returning the Banana Fairies": 14041151, + "Isles Lanky Instrument Pad/Golden Banana": 14041152, + "Japes DK Wrinkly Door/Wrinkly Door": 14041603, + "Japes Diddy Wrinkly Door/Wrinkly Door": 14041604, + "Japes Lanky Wrinkly Door/Wrinkly Door": 14041605, + "Japes Tiny Wrinkly Door/Wrinkly Door": 14041606, + "Japes Chunky Wrinkly Door/Wrinkly Door": 14041607, + "Isles Tiny Aztec Lobby Barrel/Golden Banana": 14041153, + "Aztec DK Wrinkly Door/Wrinkly Door": 14041608, + "Aztec Diddy Wrinkly Door/Wrinkly Door": 14041609, + "Aztec Lanky Wrinkly Door/Wrinkly Door": 14041610, + "Aztec Tiny Wrinkly Door/Wrinkly Door": 14041611, + "Aztec Chunky Wrinkly Door/Wrinkly Door": 14041612, + "Isles Lanky Grape Cage/Golden Banana": 14041143, + "Isles DK Coconut Cage/Golden Banana": 14041154, + "Upper Krem Isles/Isles Tiny Saxophone Pad": 14041142, + "Upper Krem Isles/Isles Fairy (Upper Krem Isle)": 14041148, + "Isles Diddy Snide Barrel/Golden Banana": 14041155, + "Isles Battle Arena 1/Crown": 14041156, + "Isles DK Bongo Pad/Golden Banana": 14041157, + "Isles Factory Lobby Box/Kasplat": 14041158, + "Isles Factory Lobby Box/Isles Fairy (Factory Lobby)": 14041159, + "Factory DK Wrinkly Door/Wrinkly Door": 14041613, + "Factory Diddy Wrinkly Door/Wrinkly Door": 14041614, + "Factory Lanky Wrinkly Door/Wrinkly Door": 14041615, + "Factory Tiny Wrinkly Door/Wrinkly Door": 14041616, + "Factory Chunky Wrinkly Door/Wrinkly Door": 14041617, + "Isles Tiny Galleon Lobby Swim/Golden Banana": 14041160, + "Isles Kasplat: Galleon Lobby/Kasplat": 14041161, + "Galleon DK Hint Door/Wrinkly Door": 14041618, + "Galleon Diddy Hint Door/Wrinkly Door": 14041619, + "Galleon Lanky Hint Door/Wrinkly Door": 14041620, + "Galleon Tiny Hint Door/Wrinkly Door": 14041621, + "Galleon Chunky Hint Door/Wrinkly Door": 14041622, + "Isles Dirt: Cabin Isle/Rainbow Coin": 14041676, + "Isles Diddy Peanut Cage/Golden Banana": 14041162, + "Isles Diddy Summit Barrel/Golden Banana": 14041163, + "Isles Dirt: Aztec Roof/Rainbow Coin": 14041678, + "Isles Battle Arena 2 (Fungi Lobby)/Crown": 14041164, + "Isles Fairy (Fungi Lobby)/Fairy": 14041165, + "Forest DK Hint Door/Wrinkly Door": 14041623, + "Forest Diddy Hint Door/Wrinkly Door": 14041624, + "Forest Lanky Hint Door/Wrinkly Door": 14041625, + "Forest Tiny Hint Door/Wrinkly Door": 14041626, + "Forest Chunky Hint Door/Wrinkly Door": 14041627, + "Isles DK Caves Lava/Golden Banana": 14041166, + "Isles Diddy Guitar Pad/Golden Banana": 14041167, + "Isles Kasplat: Caves Lobby Punch/Kasplat": 14041168, + "Caves DK Hint Door/Wrinkly Door": 14041628, + "Caves Diddy Hint Door/Wrinkly Door": 14041629, + "Caves Lanky Hint Door/Wrinkly Door": 14041630, + "Caves Tiny Hint Door/Wrinkly Door": 14041631, + "Caves Chunky Hint Door/Wrinkly Door": 14041632, + "Upper Castle Lobby/Isles Lanky Castle Lobby Barrel": 14041169, + "Isles Kasplat: Castle Lobby/Kasplat": 14041170, + "Castle DK Hint Door/Wrinkly Door": 14041633, + "Castle Diddy Hint Door/Wrinkly Door": 14041634, + "Castle Lanky Hint Door/Wrinkly Door": 14041635, + "Castle Tiny Hint Door/Wrinkly Door": 14041636, + "Castle Chunky Hint Door/Wrinkly Door": 14041637, + "Upper Castle Lobby/Isles Dirt: Castle Lobby": 14041688, + "Isles Chunky Helm Lobby Barrel/Golden Banana": 14041171, + "Isles Kasplat: Helm Lobby/Kasplat": 14041172, + "Medals/Forest DK Medal": 14041320, + "Medals/Forest Diddy Medal": 14041321, + "Medals/Forest Lanky Medal": 14041322, + "Medals/Forest Tiny Medal": 14041323, + "Medals/Forest Chunky Medal": 14041324, + "Medals/Forest DK Half-Medal": 14042349, + "Medals/Forest Diddy Half-Medal": 14042350, + "Medals/Forest Lanky Half-Medal": 14042351, + "Medals/Forest Tiny Half-Medal": 14042352, + "Medals/Forest Chunky Half-Medal": 14042353, + "Medals/Boss": 14041354, + "Forest Chunky Minecart/Golden Banana": 14041325, + "Forest Diddy Top of Mushroom Barrel/Golden Banana": 14041326, + "Inside the Mushroom/Forest Tiny Mushroom Barrel": 14041327, + "Forest Kasplat: Lower Mushroom Exterior/Kasplat": 14041329, + "Forest DK Baboon Blast/Golden Banana": 14041328, + "Inside the Mushroom/Forest Kasplat: Inside Giant Mushroom": 14041331, + "Inside the Mushroom/Forest DK Mushroom Cannons": 14041330, + "Forest Kasplat: Mushroom Night Door/Kasplat": 14041332, + "Forest Battle Arena: High Ladder Platform/Crown": 14041333, + "Face Puzzle Room/Forest Chunky Face Puzzle": 14041334, + "Zinger Room/Forest Lanky Zinger Room": 14041335, + "Forest Lanky Coloured Mushroom Slam/Golden Banana": 14041336, + "Forest Diddy Owl Race/Golden Banana": 14041337, + "Forest Lanky Rabbit Race/Golden Banana": 14041338, + "Forest Kasplat: Under Owl Tree/Kasplat": 14041339, + "Forest Crate: Near Owl Tree/Crate": 14041697, + "Forest Anthill/Forest Tiny Anthill Banana": 14041340, + "Forest Anthill/Forest Tiny Bean": 14041353, + "Forest DK Mill Levers/Golden Banana": 14041341, + "Winch Room/Forest Diddy Winch Cage": 14041342, + "Forest Dirt: Near Mills Grass/Rainbow Coin": 14041680, + "Forest Crate: Behind Dark Attic/Crate": 14041699, + "Forest Tiny Spider Boss/Golden Banana": 14041343, + "Forest Chunky Keg Crushing/Golden Banana": 14041344, + "Dark Rafters/Forest Diddy Dark Rafters": 14041345, + "Dark Rafters/Forest Fairy (Dark Rafters)": 14041346, + "Forest Lanky Attic Shooting/Golden Banana": 14041347, + "Forest Kasplat: Behind DK's Barn/Kasplat": 14041348, + "Forest Crate: Near Thornvine Barn/Crate": 14041698, + "Forest Donkey Thornvine Barn Barrel/Golden Banana": 14041349, + "Forest Crate: In Thornvine Barn/Crate": 14041700, + "Forest Fairy (Thornvine Barn)/Fairy": 14041350, + "Forest Tiny Top of Beanstalk/Golden Banana": 14041351, + "Forest Chunky Apple Rescue/Golden Banana": 14041352, + "Forest Dirt: Beanstalk/Rainbow Coin": 14041681, + "Helm Battle Arena/Crown": 14041433, + "Helm DK Medal/Medal": 14041434, + "Helm Chunky Medal/Medal": 14041435, + "Helm Tiny Medal/Medal": 14041436, + "Helm Lanky Medal/Medal": 14041437, + "Helm Diddy Medal/Medal": 14041438, + "The End of Helm/Key": 14041441, + "Helm Fairy (Key 8 Room)/Fairy 1": 14041439, + "Helm Fairy (Key 8 Room)/Fairy 2": 14041440, + "Medals/Japes DK Medal": 14041174, + "Medals/Japes Diddy Medal": 14041175, + "Medals/Japes Lanky Medal": 14041176, + "Medals/Japes Tiny Medal": 14041177, + "Medals/Japes Chunky Medal": 14041178, + "Medals/Japes DK Half-Medal": 14042329, + "Medals/Japes Diddy Half-Medal": 14042330, + "Medals/Japes Lanky Half-Medal": 14042331, + "Medals/Japes Tiny Half-Medal": 14042332, + "Medals/Japes Chunky Half-Medal": 14042333, + "Medals/Boss": 14041208, + "Japes DK Floor Cage Banana/Golden Banana": 14041182, + "Japes Chunky Boulder/Golden Banana": 14041188, + "Japes Lanky Timed Cage Banana/Golden Banana": 14041186, + "Diddy Cage/Diddy Kong's Cage": 14041179, + "Diddy Cage/Japes in Front of Diddy Cage": 14041180, + "Diddy Cage/Japes Free Diddy Item": 14041181, + "Japes Crate: Behind the Mountain/Crate": 14041689, + "Japes Chunky Timed Cage Banana/Golden Banana": 14041189, + "Japes Diddy Timed Cage Banana/Golden Banana": 14041184, + "Japes Battle Arena (Near Funky)/Crown": 14041190, + "Japes Tiny Timed Cage Banana/Golden Banana": 14041187, + "Japes Dirt: Painting Hill/Rainbow Coin": 14041673, + "Japes Diddy Top of Mountain/Golden Banana": 14041185, + "Japes DK Baboon Blast/Golden Banana": 14041183, + "Japes Diddy Peanut Tunnel/Golden Banana": 14041191, + "Japes Lanky Grape Gate Barrel/Golden Banana": 14041192, + "Japes Tiny Feather Gate Barrel/Golden Banana": 14041193, + "Japes Kasplat: Hive Tunnel Lower/Kasplat": 14041194, + "Japes Kasplat: Hive Tunnel Upper/Kasplat": 14041195, + "Japes Tiny Stump/Golden Banana": 14041196, + "Japes Chunky Giant Bonus Barrel/Golden Banana": 14041197, + "Japes Tiny Beehive/Golden Banana": 14041198, + "Japes Lanky Slope Barrel/Golden Banana": 14041199, + "Japes Kasplat: Near Painting Room/Kasplat": 14041200, + "Japes Kasplat: By Lanky Slope Bonus/Kasplat": 14041201, + "Japes Fairy (Rambi Door Pool)/Fairy": 14041202, + "Japes Crate: In the Rambi Cave/Crate": 14041690, + "Painting Room/Japes Lanky Zingers": 14041203, + "Painting Room/Japes Fairy (Painting Room)": 14041204, + "Japes Diddy Minecart/Golden Banana": 14041205, + "Japes Chunky Underground/Golden Banana": 14041206, + "Japes Kasplat: Underground/Kasplat": 14041207, + "Jungle Japes Enemy: Start/Enemy": 14041718, + "Jungle Japes Enemy: Diddy Cavern/Enemy": 14041719, + "Jungle Japes Enemy: Tunnel (0)/Enemy": 14041720, + "Jungle Japes Enemy: Tunnel (1)/Enemy": 14041721, + "Jungle Japes Enemy: Storm (0)/Enemy": 14041722, + "Jungle Japes Enemy: Storm (1)/Enemy": 14041723, + "Jungle Japes Enemy: Storm (2)/Enemy": 14041724, + "Jungle Japes Enemy: Hive (0)/Enemy": 14041725, + "Jungle Japes Enemy: Hive (1)/Enemy": 14041726, + "Jungle Japes Enemy: Hive (2)/Enemy": 14041727, + "Jungle Japes Enemy: Hive (3)/Enemy": 14041728, + "Jungle Japes Enemy: Hive (4)/Enemy": 14041729, + "Jungle Japes Enemy: Killed In Demo/Enemy": 14041730, + "Jungle Japes Enemy: Near Underground/Enemy": 14041731, + "Jungle Japes Enemy: Near Painting (0)/Enemy": 14041732, + "Jungle Japes Enemy: Near Painting (1)/Enemy": 14041733, + "Jungle Japes Enemy: Near Painting (2)/Enemy": 14041734, + "Jungle Japes Enemy: Mountain/Enemy": 14041735, + "Jungle Japes Enemy: Feather Tunnel/Enemy": 14041736, + "Jungle Japes Enemy: Middle Tunnel/Enemy": 14041737, + "Japes Mountain Enemy: Start (0)/Enemy": 14041740, + "Japes Mountain Enemy: Start (1)/Enemy": 14041741, + "Japes Mountain Enemy: Start (2)/Enemy": 14041742, + "Japes Mountain Enemy: Start (3)/Enemy": 14041743, + "Japes Mountain Enemy: Start (4)/Enemy": 14041744, + "Japes Mountain Enemy: Near Gate Switch (0)/Enemy": 14041745, + "Japes Mountain Enemy: Near Gate Switch (1)/Enemy": 14041746, + "Japes Mountain Enemy: Hi Lo/Enemy": 14041747, + "Japes Mountain Enemy: Conveyor (0)/Enemy": 14041748, + "Japes Mountain Enemy: Conveyor (1)/Enemy": 14041749, + "Japes Tiny Hive Enemy: First Room/Enemy": 14041750, + "Japes Tiny Hive Enemy: Second Room (0)/Enemy": 14041751, + "Japes Tiny Hive Enemy: Second Room (1)/Enemy": 14041752, + "Japes Tiny Hive Enemy: Third Room (0)/Enemy": 14041753, + "Japes Tiny Hive Enemy: Third Room (1)/Enemy": 14041754, + "Japes Tiny Hive Enemy: Third Room (2)/Enemy": 14041755, + "Japes Tiny Hive Enemy: Third Room (3)/Enemy": 14041756, + "Japes Tiny Hive Enemy: Main Room/Enemy": 14041757, + "Angry Aztec Enemy: Vase Room (0)/Enemy": 14041758, + "Angry Aztec Enemy: Vase Room (1)/Enemy": 14041759, + "Angry Aztec Enemy: Vase Room (2)/Enemy": 14041760, + "Angry Aztec Enemy: Tunnel Pad (0)/Enemy": 14041761, + "Angry Aztec Enemy: Tunnel Cage (0)/Enemy": 14041762, + "Angry Aztec Enemy: Tunnel Cage (1)/Enemy": 14041763, + "Angry Aztec Enemy: Tunnel Cage (2)/Enemy": 14041764, + "Angry Aztec Enemy: Starting Tunnel (0)/Enemy": 14041765, + "Angry Aztec Enemy: Starting Tunnel (1)/Enemy": 14041766, + "Angry Aztec Enemy: Oasis Door/Enemy": 14041767, + "Angry Aztec Enemy: Tunnel Cage (3)/Enemy": 14041768, + "Angry Aztec Enemy: Outside Llama/Enemy": 14041769, + "Angry Aztec Enemy: Outside Tower/Enemy": 14041770, + "Angry Aztec Enemy: Tunnel Pad (1)/Enemy": 14041771, + "Angry Aztec Enemy: Near Candy/Enemy": 14041772, + "Angry Aztec Enemy: Around Totem/Enemy": 14041773, + "Angry Aztec Enemy: Starting Tunnel (2)/Enemy": 14041774, + "Angry Aztec Enemy: Starting Tunnel (3)/Enemy": 14041775, + "Angry Aztec Enemy: Outside Snide/Enemy": 14041776, + "Angry Aztec Enemy: Outside 5DT/Enemy": 14041777, + "Angry Aztec Enemy: Near Sealed Quicksand Tunnel/Enemy": 14041778, + "Aztec Donkey 5DTemple Enemy: Start Trap (0)/Enemy": 14041779, + "Aztec Donkey 5DTemple Enemy: Start Trap (1)/Enemy": 14041780, + "Aztec Donkey 5DTemple Enemy: Start Trap (2)/Enemy": 14041781, + "Aztec Donkey 5DTemple Enemy: End Trap (0)/Enemy": 14041782, + "Aztec Donkey 5DTemple Enemy: End Trap (1)/Enemy": 14041783, + "Aztec Donkey 5DTemple Enemy: End Trap (2)/Enemy": 14041784, + "Aztec Donkey 5DTemple Enemy: End Path (0)/Enemy": 14041785, + "Aztec Donkey 5DTemple Enemy: End Path (1)/Enemy": 14041786, + "Aztec Donkey 5DTemple Enemy: Start Path/Enemy": 14041787, + "Aztec Diddy 5DTemple Enemy: End Trap (0)/Enemy": 14041788, + "Aztec Diddy 5DTemple Enemy: End Trap (1)/Enemy": 14041789, + "Aztec Diddy 5DTemple Enemy: End Trap (2)/Enemy": 14041790, + "Aztec Diddy 5DTemple Enemy: Start Left (0)/Enemy": 14041791, + "Aztec Diddy 5DTemple Enemy: Start Left (1)/Enemy": 14041792, + "Aztec Diddy 5DTemple Enemy: Reward/Enemy": 14041793, + "Aztec Diddy 5DTemple Enemy: Second Switch/Enemy": 14041794, + "Aztec Lanky 5DTemple Enemy: Joining Paths/Enemy": 14041795, + "Aztec Lanky 5DTemple Enemy: End Trap/Enemy": 14041796, + "Aztec Lanky 5DTemple Enemy: Reward/Enemy": 14041797, + "Aztec Tiny 5DTemple Enemy: Start Right Front/Enemy": 14041798, + "Aztec Tiny 5DTemple Enemy: Start Left Back/Enemy": 14041799, + "Aztec Tiny 5DTemple Enemy: Start Right Back/Enemy": 14041800, + "Aztec Tiny 5DTemple Enemy: Start Left Front/Enemy": 14041801, + "Aztec Tiny 5DTemple Enemy: Reward (0)/Enemy": 14041802, + "Aztec Tiny 5DTemple Enemy: Reward (1)/Enemy": 14041803, + "Aztec Tiny 5DTemple Enemy: Dead End (0)/Enemy": 14041804, + "Aztec Tiny 5DTemple Enemy: Dead End (1)/Enemy": 14041805, + "Aztec Chunky 5DTemple Enemy: Start Right/Enemy": 14041806, + "Aztec Chunky 5DTemple Enemy: Start Left/Enemy": 14041807, + "Aztec Chunky 5DTemple Enemy: Second Right/Enemy": 14041808, + "Aztec Chunky 5DTemple Enemy: Second Left/Enemy": 14041809, + "Aztec Chunky 5DTemple Enemy: Reward/Enemy": 14041810, + "Aztec Llama Temple Enemy: Kong Free Instrument/Enemy": 14041811, + "Aztec Llama Temple Enemy: Dino Instrument/Enemy": 14041812, + "Aztec Llama Temple Enemy: Matching (0)/Enemy": 14041813, + "Aztec Llama Temple Enemy: Matching (1)/Enemy": 14041814, + "Aztec Llama Temple Enemy: Right/Enemy": 14041815, + "Aztec Llama Temple Enemy: Left/Enemy": 14041816, + "Aztec Llama Temple Enemy: Melon Crate/Enemy": 14041817, + "Aztec Llama Temple Enemy: Slam Switch/Enemy": 14041818, + "Aztec Tiny Temple Enemy: Guard Rotating (0)/Enemy": 14041819, + "Aztec Tiny Temple Enemy: Guard Rotating (1)/Enemy": 14041820, + "Aztec Tiny Temple Enemy: Main Room (0)/Enemy": 14041821, + "Aztec Tiny Temple Enemy: Main Room (1)/Enemy": 14041822, + "Aztec Tiny Temple Enemy: Main Room (2)/Enemy": 14041823, + "Aztec Tiny Temple Enemy: Kong Room (0)/Enemy": 14041824, + "Aztec Tiny Temple Enemy: Kong Room (1)/Enemy": 14041825, + "Aztec Tiny Temple Enemy: Kong Room (2)/Enemy": 14041826, + "Aztec Tiny Temple Enemy: Kong Room (3)/Enemy": 14041827, + "Aztec Tiny Temple Enemy: Kong Room (4)/Enemy": 14041828, + "Frantic Factory Enemy: Candy Cranky (0)/Enemy": 14041829, + "Frantic Factory Enemy: Candy Cranky (1)/Enemy": 14041830, + "Frantic Factory Enemy: Lobby Left/Enemy": 14041831, + "Frantic Factory Enemy: Lobby Right/Enemy": 14041832, + "Frantic Factory Enemy: Storage Room/Enemy": 14041833, + "Frantic Factory Enemy: Block Tower (0)/Enemy": 14041834, + "Frantic Factory Enemy: Block Tower (1)/Enemy": 14041835, + "Frantic Factory Enemy: Block Tower (2)/Enemy": 14041836, + "Frantic Factory Enemy: Tunnel To Hatch/Enemy": 14041837, + "Frantic Factory Enemy: Tunnel To Prod (0)/Enemy": 14041838, + "Frantic Factory Enemy: Tunnel To Prod (1)/Enemy": 14041839, + "Frantic Factory Enemy: Tunnel To Block Tower/Enemy": 14041840, + "Frantic Factory Enemy: Tunnel To Race (0)/Enemy": 14041841, + "Frantic Factory Enemy: Tunnel To Race (1)/Enemy": 14041842, + "Frantic Factory Enemy: Low Warp 4/Enemy": 14041843, + "Frantic Factory Enemy: Diddy Switch/Enemy": 14041844, + "Frantic Factory Enemy: To Block Tower Tunnel/Enemy": 14041845, + "Frantic Factory Enemy: Dark Room (0)/Enemy": 14041846, + "Frantic Factory Enemy: Dark Room (1)/Enemy": 14041847, + "Frantic Factory Lobby Enemy: Enemy (0)/Enemy": 14041848, + "Gloomy Galleon Enemy: Chest Room (0)/Enemy": 14041849, + "Gloomy Galleon Enemy: Chest Room (1)/Enemy": 14041850, + "Gloomy Galleon Enemy: Near Vine Cannon/Enemy": 14041851, + "Gloomy Galleon Enemy: Cranky Cannon/Enemy": 14041852, + "Gloomy Galleon Enemy: Peanut Tunnel/Enemy": 14041853, + "Gloomy Galleon Enemy: Coconut Tunnel/Enemy": 14041854, + "Lighthouse/Galleon Lighthouse Enemy: Enemy (0)": 14041855, + "Lighthouse/Galleon Lighthouse Enemy: Enemy (1)": 14041856, + "Fungi Forest Enemy: Hollow Tree (0)/Enemy": 14041857, + "Fungi Forest Enemy: Hollow Tree (1)/Enemy": 14041858, + "Fungi Forest Enemy: Hollow Tree Entrance/Enemy": 14041859, + "Fungi Forest Enemy: Tree Melon Crate (0)/Enemy": 14041860, + "Fungi Forest Enemy: Tree Melon Crate (1)/Enemy": 14041861, + "Fungi Forest Enemy: Tree Melon Crate (2)/Enemy": 14041862, + "Fungi Forest Enemy: Apple Gauntlet (0)/Enemy": 14041863, + "Fungi Forest Enemy: Apple Gauntlet (1)/Enemy": 14041864, + "Fungi Forest Enemy: Apple Gauntlet (2)/Enemy": 14041865, + "Fungi Forest Enemy: Apple Gauntlet (3)/Enemy": 14041866, + "Fungi Forest Enemy: Near Beanstalk (0)/Enemy": 14041867, + "Fungi Forest Enemy: Near Beanstalk (1)/Enemy": 14041868, + "Fungi Forest Enemy: Green Tunnel/Enemy": 14041869, + "Fungi Forest Enemy: Near Low Warp 5/Enemy": 14041870, + "Fungi Forest Enemy: Near Pink Tunnel Bounce Tag/Enemy": 14041871, + "Fungi Forest Enemy: Near Giant Mushroom Rocketbarrel/Enemy": 14041872, + "Fungi Forest Enemy: Between Yellow Tunnel And RB/Enemy": 14041873, + "Fungi Forest Enemy: Near Cranky/Enemy": 14041874, + "Fungi Forest Enemy: Near Pink Tunnel Giant Mushroom/Enemy": 14041875, + "Fungi Forest Enemy: Giant Mushroom Rear Tag/Enemy": 14041876, + "Fungi Forest Enemy: Near Face Puzzle/Enemy": 14041877, + "Fungi Forest Enemy: Near Crown/Enemy": 14041878, + "Fungi Forest Enemy: Near High Warp 5/Enemy": 14041879, + "Fungi Forest Enemy: Top Of Mushroom/Enemy": 14041880, + "Fungi Forest Enemy: Near Apple Dropoff/Enemy": 14041881, + "Fungi Forest Enemy: Near DKPortal/Enemy": 14041882, + "Fungi Forest Enemy: Near Well Tag/Enemy": 14041883, + "Fungi Forest Enemy: Yellow Tunnel (0)/Enemy": 14041884, + "Fungi Forest Enemy: Yellow Tunnel (1)/Enemy": 14041885, + "Fungi Forest Enemy: Yellow Tunnel (2)/Enemy": 14041886, + "Fungi Forest Enemy: Yellow Tunnel (3)/Enemy": 14041887, + "Fungi Forest Enemy: Near Snide/Enemy": 14041888, + "Fungi Forest Enemy: Near the hidden Rainbow Coin/Enemy": 14041889, + "Fungi Forest Enemy: Near BBlast/Enemy": 14041890, + "Fungi Forest Enemy: Near Dark Attic/Enemy": 14041891, + "Fungi Forest Enemy: Near Well Exit/Enemy": 14041892, + "Fungi Forest Enemy: Near Blue Tunnel/Enemy": 14041893, + "Fungi Forest Enemy: Thornvine (0)/Enemy": 14041894, + "Fungi Forest Enemy: Thornvine (1)/Enemy": 14041895, + "Fungi Forest Enemy: Thornvine (2)/Enemy": 14041896, + "Fungi Forest Enemy: Thornvine Entrance/Enemy": 14041897, + "Forest Anthill/Forest Anthill Enemy: Gauntlet (0)": 14041898, + "Forest Anthill/Forest Anthill Enemy: Gauntlet (1)": 14041899, + "Forest Anthill/Forest Anthill Enemy: Gauntlet (2)": 14041900, + "Forest Anthill/Forest Anthill Enemy: Gauntlet (3)": 14041901, + "Winch Room/Forest Winch Room Enemy: Enemy": 14041902, + "Forest Thornvine Barn Enemy: Enemy/Enemy": 14041903, + "Forest Mill Front Enemy: Enemy/Enemy": 14041904, + "Forest Mill Back Enemy: Enemy/Enemy": 14041905, + "Inside the Mushroom/Forest Giant Mushroom Enemy: Above Night Door": 14041906, + "Inside the Mushroom/Forest Giant Mushroom Enemy: Path (0)": 14041907, + "Inside the Mushroom/Forest Giant Mushroom Enemy: Path (1)": 14041908, + "Zinger Room/Forest Lanky Zingers Room Enemy: Enemy (0)": 14041909, + "Zinger Room/Forest Lanky Zingers Room Enemy: Enemy (1)": 14041910, + "Face Puzzle Room/Forest Chunky Face Room Enemy: Enemy": 14041911, + "Crystal Caves Enemy: Start/Enemy": 14041912, + "Crystal Caves Enemy: Near Ice Castle/Enemy": 14041913, + "Crystal Caves Enemy: Outside 5DC/Enemy": 14041914, + "Crystal Caves Enemy: 1DC Waterfall/Enemy": 14041915, + "Crystal Caves Enemy: Near Funky/Enemy": 14041916, + "Crystal Caves Enemy: Near Snide/Enemy": 14041917, + "Crystal Caves Enemy: Near Bonus Room/Enemy": 14041918, + "Crystal Caves Enemy: 1DC Headphones/Enemy": 14041919, + "Caves DK 5 Door Igloo/Caves Donkey Igloo Enemy: Right": 14041920, + "Caves DK 5 Door Igloo/Caves Donkey Igloo Enemy: Left": 14041921, + "Caves Tiny 5 Door Igloo/Caves Tiny Igloo Enemy: Big Enemy": 14041922, + "Caves Lanky Sprint Cabin/Caves Lanky Cabin Enemy: Near": 14041923, + "Creepy Castle Enemy: Near Bridge (0)/Enemy": 14041924, + "Creepy Castle Enemy: Near Bridge (1)/Enemy": 14041925, + "Creepy Castle Enemy: Wooden Extrusion (0)/Enemy": 14041926, + "Creepy Castle Enemy: Wooden Extrusion (1)/Enemy": 14041927, + "Creepy Castle Enemy: Near Shed/Enemy": 14041928, + "Creepy Castle Enemy: Near Library/Enemy": 14041929, + "Creepy Castle Enemy: Near Tower/Enemy": 14041930, + "Creepy Castle Enemy: Museum Steps/Enemy": 14041931, + "Creepy Castle Enemy: Near Low Cave/Enemy": 14041932, + "Creepy Castle Enemy: Path To Low Kasplat/Enemy": 14041933, + "Creepy Castle Enemy: Low TnS/Enemy": 14041934, + "Creepy Castle Enemy: Path To Dungeon/Enemy": 14041935, + "Creepy Castle Enemy: Near Headphones/Enemy": 14041936, + "Creepy Castle Lobby Enemy: Left/Enemy": 14041937, + "Creepy Castle Lobby Enemy: Far Right/Enemy": 14041938, + "Creepy Castle Lobby Enemy: Near Right/Enemy": 14041939, + "Castle Ballroom Enemy: Start/Enemy": 14041940, + "Castle Dungeon Enemy: Face Room/Enemy": 14041941, + "Castle Dungeon Enemy: Chair Room/Enemy": 14041942, + "Castle Dungeon Enemy: Outside Lanky Room/Enemy": 14041943, + "Castle Lower Cave Enemy: Near Crypt/Enemy": 14041944, + "Castle Lower Cave Enemy: Stair Right/Enemy": 14041945, + "Castle Lower Cave Enemy: Stair Left/Enemy": 14041946, + "Castle Lower Cave Enemy: Near Mausoleum/Enemy": 14041947, + "Castle Lower Cave Enemy: Near Funky/Enemy": 14041948, + "Castle Lower Cave Enemy: Near Tag/Enemy": 14041949, + "Castle Diddy Crypt/Castle Crypt Enemy: Diddy Coffin (0)": 14041950, + "Castle Diddy Crypt/Castle Crypt Enemy: Diddy Coffin (1)": 14041951, + "Castle Diddy Crypt/Castle Crypt Enemy: Diddy Coffin (2)": 14041952, + "Castle Diddy Crypt/Castle Crypt Enemy: Diddy Coffin (3)": 14041953, + "Castle Chunky Crypt/Castle Crypt Enemy: Chunky Coffin (0)": 14041954, + "Castle Chunky Crypt/Castle Crypt Enemy: Chunky Coffin (1)": 14041955, + "Castle Chunky Crypt/Castle Crypt Enemy: Chunky Coffin (2)": 14041956, + "Castle Chunky Crypt/Castle Crypt Enemy: Chunky Coffin (3)": 14041957, + "Castle DK Minecart/Castle Crypt Enemy: Minecart Entry": 14041958, + "Castle Crypt Enemy: Fork/Enemy": 14041959, + "Castle Crypt Enemy: Near Diddy/Enemy": 14041960, + "Castle Crypt Enemy: Near Chunky/Enemy": 14041961, + "Mausoleum/Castle Mausoleum Enemy: Tiny Path": 14041962, + "Mausoleum/Castle Mausoleum Enemy: Lanky Path (0)": 14041963, + "Mausoleum/Castle Mausoleum Enemy: Lanky Path (1)": 14041964, + "Castle Upper Cave Enemy: Near Dungeon/Enemy": 14041965, + "Castle Upper Cave Enemy: Near Pit/Enemy": 14041966, + "Castle Upper Cave Enemy: Near Entrance/Enemy": 14041967, + "Castle DK Library/Castle Library Enemy: Fork Left (0)": 14041968, + "Castle DK Library/Castle Library Enemy: Fork Left (1)": 14041969, + "Castle DK Library/Castle Library Enemy: Fork Center": 14041970, + "Castle DK Library/Castle Library Enemy: Fork Right": 14041971, + "Castle Museum Enemy: Main Floor (0)/Enemy": 14041972, + "Castle Museum Enemy: Main Floor (1)/Enemy": 14041973, + "Castle Museum Enemy: Main Floor (2)/Enemy": 14041974, + "Castle Museum Enemy: Main Floor (3)/Enemy": 14041975, + "Castle Museum Enemy: Start/Enemy": 14041976, + "Inside the Tree/Castle Tree Enemy: Start Room (0)": 14041977, + "Inside the Tree/Castle Tree Enemy: Start Room (1)": 14041978, + "Hideout Helm Enemy: Start (0)/Enemy": 14041979, + "Hideout Helm Enemy: Start (1)/Enemy": 14041980, + "Hideout Helm Enemy: Hill/Enemy": 14041981, + "Hideout Helm Enemy: Switch Room (0)/Enemy": 14041982, + "Hideout Helm Enemy: Switch Room (1)/Enemy": 14041983, + "Hideout Helm Enemy: Mini Room (0)/Enemy": 14041984, + "Hideout Helm Enemy: Mini Room (1)/Enemy": 14041985, + "Hideout Helm Enemy: Mini Room (2)/Enemy": 14041986, + "Hideout Helm Enemy: Mini Room (3)/Enemy": 14041987, + "Hideout Helm Enemy: DKRoom/Enemy": 14041988, + "Hideout Helm Enemy: Chunky Room (0)/Enemy": 14041989, + "Hideout Helm Enemy: Chunky Room (1)/Enemy": 14041990, + "Hideout Helm Enemy: Tiny Room/Enemy": 14041991, + "Hideout Helm Enemy: Lanky Room (0)/Enemy": 14041992, + "Hideout Helm Enemy: Lanky Room (1)/Enemy": 14041993, + "Hideout Helm Enemy: Diddy Room (0)/Enemy": 14041994, + "Hideout Helm Enemy: Diddy Room (1)/Enemy": 14041995, + "Hideout Helm Enemy: Nav Right/Enemy": 14041996, + "Hideout Helm Enemy: Nav Left/Enemy": 14041997, + "Isles Enemy: Pineapple Cage (0)/Enemy": 14041998, + "Isles Enemy: Fungi Cannon (0)/Enemy": 14041999, + "Jungle Japes Lobby Enemy: Enemy (0)/Enemy": 14041738, + "Jungle Japes Lobby Enemy: Enemy (1)/Enemy": 14041739, + "Isles Enemy: Japes Entrance/Enemy": 14042000, + "Isles Enemy: Monkeyport Pad/Enemy": 14042001, + "Isles Enemy: Upper Factory Path/Enemy": 14042002, + "Isles Enemy: Near Aztec/Enemy": 14042003, + "Isles Enemy: Fungi Cannon (1)/Enemy": 14042004, + "Isles Enemy: Pineapple Cage (1)/Enemy": 14042005, + "Isles Enemy: Lower Factory Path (0)/Enemy": 14042006, + "Isles Enemy: Lower Factory Path (1)/Enemy": 14042007, + "Isles Boulder: Near Level 2/Boulder": 14041702, + "Isles Chunky Triangle Pad/Isles Boulder: Near Level 6": 14041703, + "Aztec Boulder: Tunnel/Boulder": 14041704, + "Caves Boulder: Small/Boulder": 14041705, + "Caves Boulder: Large/Boulder": 14041706, + "Castle Boulder: Museum/Boulder": 14041707, + "Isles Lanky Instrument Pad/Isles Boulder: Japes Lobby": 14041708, + "Isles Boulder: Castle Lobby/Boulder": 14041709, + "Isles Boulder: Caves Lobby/Boulder": 14041710, + "Forest Keg: Mill Front Near/Boulder": 14041711, + "Forest Keg: Mill Front Far/Boulder": 14041712, + "Forest Keg: Mill Back/Boulder": 14041713, + "Aztec Chunky Vases/Aztec Vase: Circle": 14041714, + "Aztec Chunky Vases/Aztec Vase: Colon": 14041715, + "Aztec Chunky Vases/Aztec Vase: Triangle": 14041716, + "Aztec Chunky Vases/Aztec Vase: Plus": 14041717, + "Medals/Factory DK Medal": 14041245, + "Medals/Factory Diddy Medal": 14041246, + "Medals/Factory Lanky Medal": 14041247, + "Medals/Factory Tiny Medal": 14041248, + "Medals/Factory Chunky Medal": 14041249, + "Medals/Factory DK Half-Medal": 14042339, + "Medals/Factory Diddy Half-Medal": 14042340, + "Medals/Factory Lanky Half-Medal": 14042341, + "Medals/Factory Tiny Half-Medal": 14042342, + "Medals/Factory Chunky Half-Medal": 14042343, + "Medals/Boss": 14041280, + "Factory DK Number Game/Golden Banana": 14041250, + "Factory Diddy Block Tower/Golden Banana": 14041251, + "Factory Lanky Testing Room Barrel/Golden Banana": 14041252, + "Factory Tiny Dartboard/Golden Banana": 14041253, + "Factory Kasplat: Block Tower/Kasplat": 14041254, + "Factory Fairy (Number Game)/Fairy": 14041255, + "Factory Fairy (Near Funky's)/Fairy": 14041256, + "Factory Crate: Near Funky/Crate": 14041692, + "Factory Diddy Charge Enemies/Golden Banana": 14041257, + "Factory Chunky Toy Monster/Golden Banana": 14041259, + "Factory Kasplat: R&D/Kasplat": 14041260, + "Factory Battle Arena (Under Grate)/Crown": 14041261, + "Factory Lanky Piano Game/Golden Banana": 14041258, + "Factory Tiny Car Race/Golden Banana": 14041262, + "Factory Diddy Storage Room Barrel/Golden Banana": 14041263, + "Factory DK Power Hut/Golden Banana": 14041264, + "Chunky's Cage/Chunky Kong's Cage": 14041265, + "Chunky's Cage/Factory Free Chunky Item": 14041268, + "Factory Chunky Dark Room/Golden Banana": 14041270, + "Factory Dirt: Dark Room/Rainbow Coin": 14041675, + "Factory Kasplat: Pole to Arcade/Kasplat": 14041273, + "Factory Crate: Near Candy/Crate": 14041693, + "Factory DK Blast Course/Golden Banana": 14041267, + "Factory Tiny Mini by Arcade/Golden Banana": 14041269, + "Factory Chunky Barrel by Arcade/Golden Banana": 14041271, + "DK Arcade/Round 2": 14041266, + "Factory Kasplat: Base of Production/Kasplat": 14041272, + "Factory DK Crusher Room/Golden Banana": 14041274, + "Factory Chunky Production Timer/Golden Banana": 14041278, + "Factory Diddy Production Spring/Golden Banana": 14041275, + "Factory Lanky Production Handstand/Golden Banana": 14041276, + "Factory Tiny Production Twirl/Golden Banana": 14041277, + "Factory Kasplat: Upper Production Pipe/Kasplat": 14041279, + "Medals/Galleon DK Medal": 14041281, + "Medals/Galleon Diddy Medal": 14041282, + "Medals/Galleon Lanky Medal": 14041283, + "Medals/Galleon Tiny Medal": 14041284, + "Medals/Galleon Chunky Medal": 14041285, + "Medals/Galleon DK Half-Medal": 14042344, + "Medals/Galleon Diddy Half-Medal": 14042345, + "Medals/Galleon Lanky Half-Medal": 14042346, + "Medals/Galleon Tiny Half-Medal": 14042347, + "Medals/Galleon Chunky Half-Medal": 14042348, + "Medals/Boss": 14041319, + "Galleon Chunky Chest/Golden Banana": 14041286, + "Galleon Battle Arena (Under Cranky)/Crown": 14041288, + "Galleon Fairy (In Punch Chest)/Fairy": 14041289, + "Galleon Kasplat: Past Vines/Kasplat": 14041287, + "Galleon Chunky Cannon Game/Golden Banana": 14041290, + "Galleon Kasplat: Cannon Game Room/Kasplat": 14041291, + "Galleon Kasplat: Lighthouse Alcove/Kasplat": 14041294, + "Galleon Diddy Top of Lighthouse/Golden Banana": 14041292, + "Galleon Lanky Enguarde Chest/Golden Banana": 14041293, + "Lighthouse/Galleon Dirt: Lighthouse": 14041682, + "Lighthouse/Galleon DK Lighthouse": 14041295, + "Galleon Tiny Mermaid Reward/Golden Banana": 14041296, + "Galleon Chunky Seasick/Golden Banana": 14041297, + "Galleon Seal/Free the Seal": 14041298, + "Galleon Kasplat: Musical Cactus/Kasplat": 14041299, + "Galleon Crate: Near Cactus/Crate": 14041694, + "Galleon Seal/Seal Race": 14041300, + "Galleon Lanky Gold Tower Barrel/Golden Banana": 14041302, + "Galleon Diddy Gold Tower Barrel/Golden Banana": 14041301, + "Galleon Kasplat: Diddy Gold Tower/Kasplat": 14041303, + "Treasure Chest/Treasure Chest Far Left Clam": 14041314, + "Treasure Chest/Treasure Chest Center Clam": 14041315, + "Treasure Chest/Treasure Chest Far Right Clam": 14041316, + "Treasure Chest/Treasure Chest Close Right Clam": 14041317, + "Treasure Chest/Treasure Chest Close Left Clam": 14041318, + "Galleon Tiny Submarine Barrel/Golden Banana": 14041304, + "Galleon Diddy Mechfish/Golden Banana": 14041305, + "2-Door Ship/Lanky 2DS": 14041306, + "2-Door Ship/Tiny 2DS": 14041307, + "Galleon DK 5-Door Ship/Golden Banana": 14041308, + "Galleon Diddy 5-Door Ship/Golden Banana": 14041309, + "Galleon Lanky 5-Door Ship/Golden Banana": 14041310, + "Galleon Tiny 5-Door Ship/Golden Banana": 14041311, + "Galleon Tiny 5-Door Ship/Fairy": 14041312, + "Galleon Chunky 5-Door Ship/Golden Banana": 14041313, + "Japes Funky/Funky DK": 14041448, + "Japes Funky/Funky Diddy": 14041449, + "Japes Funky/Funky Lanky": 14041450, + "Japes Funky/Funky Tiny": 14041451, + "Japes Funky/Funky Chunky": 14041452, + "Aztec Funky/Funky DK": 14041485, + "Aztec Funky/Funky Diddy": 14041486, + "Aztec Funky/Funky Lanky": 14041487, + "Aztec Funky/Funky Tiny": 14041488, + "Aztec Funky/Funky Chunky": 14041489, + "Factory Funky/Funky DK": 14041492, + "Factory Funky/Funky Diddy": 14041493, + "Factory Funky/Funky Lanky": 14041494, + "Factory Funky/Funky Tiny": 14041495, + "Factory Funky/Funky Chunky": 14041496, + "Galleon Funky/Funky DK": 14041510, + "Galleon Funky/Funky Diddy": 14041511, + "Galleon Funky/Funky Lanky": 14041512, + "Galleon Funky/Funky Tiny": 14041513, + "Galleon Funky/Funky Chunky": 14041514, + "Forest Funky/Funky DK": 14041525, + "Forest Funky/Funky Diddy": 14041526, + "Forest Funky/Funky Lanky": 14041527, + "Forest Funky/Funky Tiny": 14041528, + "Forest Funky/Funky Chunky": 14041529, + "Caves Funky/Funky DK": 14041533, + "Caves Funky/Funky Diddy": 14041534, + "Caves Funky/Funky Lanky": 14041535, + "Caves Funky/Funky Tiny": 14041536, + "Caves Funky/Funky Chunky": 14041537, + "Castle Funky/Funky DK": 14041548, + "Castle Funky/Funky Diddy": 14041549, + "Castle Funky/Funky Lanky": 14041550, + "Castle Funky/Funky Tiny": 14041551, + "Castle Funky/Funky Chunky": 14041552, + "Aztec Candy/Candy DK": 14041455, + "Aztec Candy/Candy Diddy": 14041456, + "Aztec Candy/Candy Lanky": 14041457, + "Aztec Candy/Candy Tiny": 14041458, + "Aztec Candy/Candy Chunky": 14041459, + "Factory Candy/Candy DK": 14041498, + "Factory Candy/Candy Diddy": 14041499, + "Factory Candy/Candy Lanky": 14041500, + "Factory Candy/Candy Tiny": 14041501, + "Factory Candy/Candy Chunky": 14041502, + "Galleon Candy/Candy DK": 14041515, + "Galleon Candy/Candy Diddy": 14041516, + "Galleon Candy/Candy Lanky": 14041517, + "Galleon Candy/Candy Tiny": 14041518, + "Galleon Candy/Candy Chunky": 14041519, + "Caves Candy/Candy DK": 14041538, + "Caves Candy/Candy Diddy": 14041539, + "Caves Candy/Candy Lanky": 14041540, + "Caves Candy/Candy Tiny": 14041541, + "Caves Candy/Candy Chunky": 14041542, + "Castle Candy/Candy DK": 14041553, + "Castle Candy/Candy Diddy": 14041554, + "Castle Candy/Candy Lanky": 14041555, + "Castle Candy/Candy Tiny": 14041556, + "Castle Candy/Candy Chunky": 14041557, + "Isles Cranky/Jetpac": 14041477, + "Japes Cranky/Cranky DK": 14041443, + "Japes Cranky/Cranky Diddy": 14041444, + "Japes Cranky/Cranky Lanky": 14041445, + "Japes Cranky/Cranky Tiny": 14041446, + "Japes Cranky/Cranky Chunky": 14041447, + "Aztec Cranky/Cranky DK": 14041453, + "Aztec Cranky/Cranky Diddy": 14041454, + "Aztec Cranky/Cranky Lanky": 14041481, + "Aztec Cranky/Cranky Tiny": 14041482, + "Aztec Cranky/Cranky Chunky": 14041483, + "Factory Cranky/Cranky DK": 14041460, + "Factory Cranky/Cranky Diddy": 14041461, + "Factory Cranky/Cranky Lanky": 14041462, + "Factory Cranky/Cranky Tiny": 14041463, + "Factory Cranky/Cranky Chunky": 14041464, + "Galleon Cranky/Cranky DK": 14041504, + "Galleon Cranky/Cranky Diddy": 14041505, + "Galleon Cranky/Cranky Lanky": 14041506, + "Galleon Cranky/Cranky Tiny": 14041507, + "Galleon Cranky/Cranky Chunky": 14041508, + "Forest Cranky/Cranky DK": 14041520, + "Forest Cranky/Cranky Diddy": 14041521, + "Forest Cranky/Cranky Lanky": 14041522, + "Forest Cranky/Cranky Tiny": 14041523, + "Forest Cranky/Cranky Chunky": 14041524, + "Caves Cranky/Cranky Lanky": 14041469, + "Caves Cranky/Cranky Tiny": 14041470, + "Caves Cranky/Cranky Chunky": 14041471, + "Caves Cranky/Cranky DK": 14041531, + "Caves Cranky/Cranky Diddy": 14041532, + "Castle Cranky/Cranky DK": 14041543, + "Castle Cranky/Cranky Diddy": 14041544, + "Castle Cranky/Cranky Lanky": 14041545, + "Castle Cranky/Cranky Tiny": 14041546, + "Castle Cranky/Cranky Chunky": 14041547, + "Isles Cranky/Cranky DK": 14041558, + "Isles Cranky/Cranky Diddy": 14041559, + "Isles Cranky/Cranky Lanky": 14041560, + "Isles Cranky/Cranky Tiny": 14041561, + "Isles Cranky/Cranky Chunky": 14041562, + "Turn in 1 Blueprint/Turn in 1 Blueprint": 14041563, + "Turn in 2 Blueprints/Turn in 2 Blueprints": 14041564, + "Turn in 3 Blueprints/Turn in 3 Blueprints": 14041565, + "Turn in 4 Blueprints/Turn in 4 Blueprints": 14041566, + "Turn in 5 Blueprints/Turn in 5 Blueprints": 14041567, + "Turn in 6 Blueprints/Turn in 6 Blueprints": 14041568, + "Turn in 7 Blueprints/Turn in 7 Blueprints": 14041569, + "Turn in 8 Blueprints/Turn in 8 Blueprints": 14041570, + "Turn in 9 Blueprints/Turn in 9 Blueprints": 14041571, + "Turn in 10 Blueprints/Turn in 10 Blueprints": 14041572, + "Turn in 11 Blueprints/Turn in 11 Blueprints": 14041573, + "Turn in 12 Blueprints/Turn in 12 Blueprints": 14041574, + "Turn in 13 Blueprints/Turn in 13 Blueprints": 14041575, + "Turn in 14 Blueprints/Turn in 14 Blueprints": 14041576, + "Turn in 15 Blueprints/Turn in 15 Blueprints": 14041577, + "Turn in 16 Blueprints/Turn in 16 Blueprints": 14041578, + "Turn in 17 Blueprints/Turn in 17 Blueprints": 14041579, + "Turn in 18 Blueprints/Turn in 18 Blueprints": 14041580, + "Turn in 19 Blueprints/Turn in 19 Blueprints": 14041581, + "Turn in 20 Blueprints/Turn in 20 Blueprints": 14041582, + "Turn in 21 Blueprints/Turn in 21 Blueprints": 14041583, + "Turn in 22 Blueprints/Turn in 22 Blueprints": 14041584, + "Turn in 23 Blueprints/Turn in 23 Blueprints": 14041585, + "Turn in 24 Blueprints/Turn in 24 Blueprints": 14041586, + "Turn in 25 Blueprints/Turn in 25 Blueprints": 14041587, + "Turn in 26 Blueprints/Turn in 26 Blueprints": 14041588, + "Turn in 27 Blueprints/Turn in 27 Blueprints": 14041589, + "Turn in 28 Blueprints/Turn in 28 Blueprints": 14041590, + "Turn in 29 Blueprints/Turn in 29 Blueprints": 14041591, + "Turn in 30 Blueprints/Turn in 30 Blueprints": 14041592, + "Turn in 31 Blueprints/Turn in 31 Blueprints": 14041593, + "Turn in 32 Blueprints/Turn in 32 Blueprints": 14041594, + "Turn in 33 Blueprints/Turn in 33 Blueprints": 14041595, + "Turn in 34 Blueprints/Turn in 34 Blueprints": 14041596, + "Turn in 35 Blueprints/Turn in 35 Blueprints": 14041597, + "Turn in 36 Blueprints/Turn in 36 Blueprints": 14041598, + "Turn in 37 Blueprints/Turn in 37 Blueprints": 14041599, + "Turn in 38 Blueprints/Turn in 38 Blueprints": 14041600, + "Turn in 39 Blueprints/Turn in 39 Blueprints": 14041601, + "Turn in 40 Blueprints/Turn in 40 Blueprints": 14041602, + # Shared Shop Locations + "Isles Cranky/Cranky Shared": 14041442, + "Japes Cranky/Cranky Shared": 14041478, + "Japes Funky/Funky Shared": 14041479, + "Aztec Cranky/Cranky Shared": 14041480, + "Aztec Funky/Funky Shared": 14041484, + "Aztec Candy/Candy Shared": 14041490, + "Factory Cranky/Cranky Shared": 14041491, + "Factory Funky/Funky Shared": 14041465, + "Factory Candy/Candy Shared": 14041497, + "Galleon Cranky/Cranky Shared": 14041503, + "Galleon Funky/Funky Shared": 14041509, + "Galleon Candy/Candy Shared": 14041466, + "Forest Cranky/Cranky Shared": 14041467, + "Forest Funky/Funky Shared": 14041468, + "Caves Cranky/Cranky Shared": 14041530, + "Caves Funky/Funky Shared": 14041472, + "Caves Candy/Candy Shared": 14041473, + "Castle Cranky/Cranky Shared": 14041474, + "Castle Funky/Funky Shared": 14041475, + "Castle Candy/Candy Shared": 14041476, +} + + +# Universal Tracker integration configuration +tracker_world = { + "external_pack_key": "ut_pack_path", + "map_page_maps": ["maps/maps.json"], + "map_page_groups": [ + ("DK Isles", ["isles", "training", "snidelobby", "japeslobby", "azteclobby", "factorylobby", "galleonlobby", "forestlobby", "caveslobby", "castlelobby", "helmlobby"]), + ("Jungle Japes", ["japes", "japesunder", "japesmountain", "shellhive"]), + ("Angry Aztec", ["aztec", "tinytemple", "llamatemple", "dk5dt", "diddy5dt", "lanky5dt", "tiny5dt", "chunky5dt"]), + ("Frantic Factory", ["factory"]), + ("Gloomy Galleon", ["galleon"]), + ("Fungi Forest", ["forest", "frontmill", "rearmill", "barn"]), + ("Crystal Caves", ["caves"]), + ("Creepy Castle", ["castle", "ballroom", "museum", "crypthub", "crypt", "dungeontunnel", "dungeon"]), + ("Hideout Helm", ["helm"]), + ], + "map_page_locations": [ + "locations/japes.json", + "locations/aztec.json", + "locations/factory.json", + "locations/galleon.json", + "locations/forest.json", + "locations/caves.json", + "locations/castle.json", + "locations/helm.json", + "locations/isles.json", + "locations/shops.json", + "locations/snides.json", + "locations/japesdropsanity.json", + "locations/aztecdropsanity.json", + "locations/factorydropsanity.json", + "locations/galleondropsanity.json", + "locations/forestdropsanity.json", + "locations/cavesdropsanity.json", + "locations/castledropsanity.json", + "locations/helmdropsanity.json", + "locations/islesdropsanity.json", + ], + "map_page_setting_key": "DK64Rando_{team}_{player}_map", + "map_page_index": dk64_map_to_tab_index, + "poptracker_name_mapping": poptracker_name_mapping, +} \ No newline at end of file From f460b42b6f45bf44f54dbb825caa6231a8abc8bb Mon Sep 17 00:00:00 2001 From: UmedMuzl Date: Mon, 2 Feb 2026 21:08:49 -0600 Subject: [PATCH 2/7] lint --- __init__.py | 66 +++++++++++++++---------------- archipelago/DK64Client.py | 28 ++++++------- archipelago/Options.py | 8 ++-- archipelago/Regions.py | 30 +++++++------- archipelago/Tracker.py | 2 +- randomizer/Patching/MirrorMode.py | 12 +++++- 6 files changed, 78 insertions(+), 68 deletions(-) diff --git a/__init__.py b/__init__.py index cae5a7a6e..6312ba2ee 100644 --- a/__init__.py +++ b/__init__.py @@ -286,11 +286,12 @@ class EnableMinimalLogic(settings.Bool): class UTPackPath(settings.UserFilePath): """Path to external Universal Tracker pack .zip file. - + Download the DK64 tracker pack from https://github.com/UmedMuzl/dk64pt/releases and point this setting to the downloaded .zip file to enable map tracking in Universal Tracker. Leave empty to disable map tracking. """ + description = "Universal Tracker Pack Path (Optional)" release_branch: ReleaseVersion = ReleaseVersion("master") @@ -1111,26 +1112,26 @@ def generate_early(self): from randomizer.ShuffleCrowns import ShuffleCrowns from randomizer.ShuffleCrates import ShuffleMelonCrates from randomizer.ShufflePatches import ShufflePatches - + resetCustomLocations(self.spoiler) - + # Store custom location flags do_crown_shuffle = self.spoiler.settings.crown_placement_rando do_patch_shuffle = self.spoiler.settings.random_patches do_crate_shuffle = self.spoiler.settings.random_crates - + # Temporarily disable custom locations so Generate_Spoiler doesn't run them self.spoiler.settings.crown_placement_rando = False self.spoiler.settings.random_patches = False self.spoiler.settings.random_crates = False - + Generate_Spoiler(self.spoiler) - + # Restore settings self.spoiler.settings.crown_placement_rando = do_crown_shuffle - self.spoiler.settings.random_patches = do_patch_shuffle + self.spoiler.settings.random_patches = do_patch_shuffle self.spoiler.settings.random_crates = do_crate_shuffle - + # Now run custom location shuffles if do_crown_shuffle: crown_replacements = {} @@ -1138,11 +1139,11 @@ def generate_early(self): ShuffleCrowns(self.spoiler, crown_replacements, crown_human_replacements) self.spoiler.crown_locations = crown_replacements self.spoiler.human_crowns = dict(sorted(crown_human_replacements.items())) - + if do_patch_shuffle: human_patches = {} self.spoiler.human_patches = ShufflePatches(self.spoiler, human_patches).copy() - + if do_crate_shuffle: human_crates = {} self.spoiler.human_crates = ShuffleMelonCrates(self.spoiler, human_crates).copy() @@ -1895,7 +1896,7 @@ def get_smaller_shops_data(self) -> dict: def get_custom_location_names(self) -> dict: """Get the mapping of location IDs to custom location data. - + Returns a dictionary mapping location ID to a dict containing: - 'name': the actual custom name assigned during shuffle - 'flag': the flag ID used for checking completion in-game @@ -1904,9 +1905,9 @@ def get_custom_location_names(self) -> dict: from randomizer.Enums.Locations import Locations as DK64RLocations from randomizer.Lists.Location import LocationListOriginal as VanillaLocationList from archipelago.Regions import BASE_ID - + custom_locations = {} - + # Get all custom location IDs # Battle Arenas are not in a contiguous range, so list them explicitly battle_arena_locations = [ @@ -1923,24 +1924,24 @@ def get_custom_location_names(self) -> dict: ] dirt_range = range(DK64RLocations.RainbowCoin_Location00, DK64RLocations.RainbowCoin_Location15 + 1) crate_range = range(DK64RLocations.MelonCrate_Location00, DK64RLocations.MelonCrate_Location12 + 1) - + custom_location_ids = set(battle_arena_locations) | set(dirt_range) | set(crate_range) - + print(f"[DK64 get_custom_location_names] Checking {len(custom_location_ids)} potential custom locations") - + # Build a mapping from enum to index in LocationListOriginal enum_to_index = {location: index for index, location in enumerate(VanillaLocationList)} - + for location_enum in custom_location_ids: if location_enum in self.spoiler.LocationList: location_obj = self.spoiler.LocationList[location_enum] # Get the vanilla name to compare vanilla_name = VanillaLocationList[location_enum].name if location_enum in VanillaLocationList else None - + # Debug: Print info about Battle Arena locations if location_enum in battle_arena_locations: print(f"[DK64] Battle Arena enum {location_enum}: name='{location_obj.name}', vanilla='{vanilla_name}'") - + # Include all custom locations, even if names haven't changed # This is necessary because flags can be shuffled even if names stay the same if location_obj.name: @@ -1954,17 +1955,14 @@ def get_custom_location_names(self) -> dict: flag_id = None if location_obj.default_mapid_data and len(location_obj.default_mapid_data) > 0: flag_id = location_obj.default_mapid_data[0].flag - custom_locations[location_id] = { - 'name': location_obj.name, - 'flag': flag_id - } + custom_locations[location_id] = {"name": location_obj.name, "flag": flag_id} # Debug: print first few if len(custom_locations) <= 3: print(f" Found custom location: {location_obj.name} (ID: {location_id}, Enum: {location_enum}, Index: {index}, Flag: {flag_id}, was: {vanilla_name})") else: if location_enum in battle_arena_locations: print(f"[DK64] WARNING: Battle Arena enum {location_enum} NOT in spoiler.LocationList!") - + print(f"[DK64 get_custom_location_names] Found {len(custom_locations)} custom locations total") return custom_locations @@ -2090,8 +2088,14 @@ def fill_slot_data(self) -> dict: }, "StartingRegion": ( { - "region": self.spoiler.settings.starting_region["region"].name if hasattr(self.spoiler.settings.starting_region["region"], "name") else str(self.spoiler.settings.starting_region["region"]), - "map": self.spoiler.settings.starting_region["map"].name if hasattr(self.spoiler.settings.starting_region["map"], "name") else str(self.spoiler.settings.starting_region["map"]), + "region": ( + self.spoiler.settings.starting_region["region"].name + if hasattr(self.spoiler.settings.starting_region["region"], "name") + else str(self.spoiler.settings.starting_region["region"]) + ), + "map": ( + self.spoiler.settings.starting_region["map"].name if hasattr(self.spoiler.settings.starting_region["map"], "name") else str(self.spoiler.settings.starting_region["map"]) + ), "exit": self.spoiler.settings.starting_region["exit"], "region_name": self.spoiler.settings.starting_region["region_name"], "exit_name": self.spoiler.settings.starting_region["exit_name"], @@ -2099,14 +2103,10 @@ def fill_slot_data(self) -> dict: if hasattr(self.spoiler.settings, "starting_region") and self.spoiler.settings.starting_region else {} ), - "DKPortalLocations": ( - self.spoiler.human_entry_doors - if hasattr(self.spoiler, "human_entry_doors") and self.spoiler.human_entry_doors - else {} - ), + "DKPortalLocations": (self.spoiler.human_entry_doors if hasattr(self.spoiler, "human_entry_doors") and self.spoiler.human_entry_doors else {}), "CustomLocationNames": self.get_custom_location_names(), } - + # Debug logging for custom locations custom_locs = slot_data.get("CustomLocationNames", {}) if custom_locs: @@ -2116,7 +2116,7 @@ def fill_slot_data(self) -> dict: print(f" Location {loc_id}: {data.get('name')} (flag: {data.get('flag')})") else: print(f" Location {loc_id}: {data}") - + return slot_data def write_spoiler(self, spoiler_handle: typing.TextIO): diff --git a/archipelago/DK64Client.py b/archipelago/DK64Client.py index c38c90905..d4e7045f2 100644 --- a/archipelago/DK64Client.py +++ b/archipelago/DK64Client.py @@ -704,10 +704,10 @@ async def readChecks(self, cb): for id in checks_to_read: # Get location name (prefer custom name if available) name = self.custom_check_id_to_name.get(id, check_id_to_name.get(id)) - + # Determine which flag to check for this location check = None - + # For custom locations (crowns, dirt, crates), ONLY use the custom flag # Do not fall back to location_name_to_flag as that would use vanilla flags if id in self.custom_check_id_to_flag: @@ -715,7 +715,7 @@ async def readChecks(self, cb): else: # For non-custom locations, use the vanilla flag mapping check = location_name_to_flag.get(name) - + if check: # Check if this flag is set in memory check_status = self.getCheckStatus("location", check) @@ -1167,40 +1167,40 @@ def update_custom_location_names(self): for id_str, data in custom_location_data.items(): loc_id = int(id_str) if isinstance(data, dict): - self.custom_check_id_to_name[loc_id] = data.get('name') - if data.get('flag') is not None: - flag_id = data.get('flag') + self.custom_check_id_to_name[loc_id] = data.get("name") + if data.get("flag") is not None: + flag_id = data.get("flag") self.custom_check_id_to_flag[loc_id] = flag_id # Build reverse mapping: flag_id -> location_id self.custom_flag_to_check_id[flag_id] = loc_id else: # Backwards compatibility: if data is just a string (old format) self.custom_check_id_to_name[loc_id] = data - + # Also update the client's dictionaries self.client.custom_check_id_to_name = self.custom_check_id_to_name self.client.custom_check_id_to_flag = self.custom_check_id_to_flag self.client.custom_flag_to_check_id = self.custom_flag_to_check_id - + # Update the location_names lookup used by Archipelago's notification system # We need to inject custom names so they take priority over base names - if hasattr(self, 'location_names') and self.location_names: + if hasattr(self, "location_names") and self.location_names: logger.info(f"Updating location_names with {len(self.custom_check_id_to_name)} custom location names") try: # Get the game's location store ChainMap if self.game in self.location_names._game_store: game_store = self.location_names._game_store[self.game] - + # Create our custom names dict custom_names_dict = {loc_id: name for loc_id, name in self.custom_check_id_to_name.items() if name} - + # Use new_child() to prepend our custom names to the existing ChainMap # This modifies the ChainMap in place and ensures any existing references see the update updated_chain = game_store.new_child(custom_names_dict) self.location_names._game_store[self.game] = updated_chain - + logger.info(f"Successfully injected {len(custom_names_dict)} custom location names") - + # Verify a few for loc_id in list(custom_names_dict.keys())[:3]: verified_name = self.location_names.lookup_in_game(loc_id, self.game) @@ -1211,7 +1211,7 @@ def update_custom_location_names(self): logger.error(f"Failed to update location_names: {e}", exc_info=True) else: logger.warning(f"location_names not available for update") - + logger.info(f"Loaded {len(self.custom_check_id_to_name)} custom location names from slot_data") logger.info(f"Built reverse mapping with {len(self.custom_flag_to_check_id)} flag->location_id entries") # Debug: print first few custom locations diff --git a/archipelago/Options.py b/archipelago/Options.py index cdc9b3fb0..dfe0fee96 100644 --- a/archipelago/Options.py +++ b/archipelago/Options.py @@ -179,7 +179,7 @@ class StartingMoveCount(Range): class KroolShuffle(Choice): """Whether or not K. Rool can be fightable in T&S Bosses and vice versa. - + "off": K. Rool can only appear in the final fight. "krool_only": K. Rool can appear in T&S bosses, but T&S can't appear in the final fight. "full_shuffle": K. Rool and T&S bosses can be shuffled between eachother. @@ -193,6 +193,7 @@ class KroolShuffle(Choice): default = 0 + class AllowedBosses(OptionList): """Determines which bosses are in the pool. If not enough bosses are selected, it will fill the pool with duplicate bosses""" @@ -201,6 +202,7 @@ class AllowedBosses(OptionList): valid_keys: {"Armydillo 1", "Dogadon 1", "Mad Jack", "Pufftoss", "Dogadon 2", "Armydillo 2", "Kutout", "DK phase", "Diddy Phase", "Lanky Phase", "Tiny Phase", "Chunky Phase"} default = ["Armydillo 1", "Dogadon 1", "Mad Jack", "Pufftoss", "Dogadon 2", "Armydillo 2", "Kutout", "DK phase", "Diddy Phase", "Lanky Phase", "Tiny Phase", "Chunky Phase"] + class TrapFillPercentage(Range): """Replace a percentage of junk items in the item pool with random traps.""" @@ -432,7 +434,7 @@ class RandomPatches(Toggle): ## TODO: Figure this out # class CBRando(Toggle): # """Randomizes the locations of Colored Bananas throughout the levels. - + # This does NOT make individual bananas checks - they remain collectibles that count toward medals. # """ @@ -1451,7 +1453,7 @@ class DKPortalLocationRando(Choice): """Randomize the locations of DK Portals within levels. DK Portals are the exits that return you from a level to its lobby. - + - off: DK Portals remain in their vanilla locations - main_only: DK Portals can only appear in main level areas (not bonus barrels, buildings, etc.) - all: DK Portals can appear anywhere in the level diff --git a/archipelago/Regions.py b/archipelago/Regions.py index e857e5493..bc1fa3e1a 100644 --- a/archipelago/Regions.py +++ b/archipelago/Regions.py @@ -113,9 +113,7 @@ def create_regions(multiworld: MultiWorld, player: int, spoiler: Spoiler, option # Build location table from spoiler's LocationList (which may have custom locations) all_locations_dynamic = { - spoiler.LocationList[location].name: (BASE_ID + index) - for index, location in enumerate(DK64RLocation.LocationListOriginal) - if spoiler.LocationList[location].type != Types.EnemyPhoto + spoiler.LocationList[location].name: (BASE_ID + index) for index, location in enumerate(DK64RLocation.LocationListOriginal) if spoiler.LocationList[location].type != Types.EnemyPhoto } all_locations_dynamic.update({"Victory": 0x00}) # Temp for generating goal location @@ -513,7 +511,9 @@ def create_region( # CURRENTLY UNUSED - for some reason some Lanky shops are inaccessible?? -def create_shop_region(multiworld: MultiWorld, player: int, region_name: str, region_obj: DK64Region, location_logics: typing.List[LocationLogic], settings: Settings, all_locations_dynamic: typing.Dict[str, int]) -> Region: +def create_shop_region( + multiworld: MultiWorld, player: int, region_name: str, region_obj: DK64Region, location_logics: typing.List[LocationLogic], settings: Settings, all_locations_dynamic: typing.Dict[str, int] +) -> Region: """Create a region for the given player's world.""" # Shop regions have relatively straightforward logic that can be streamlined for performance purposes new_region = Region(region_name, player, multiworld) @@ -630,7 +630,7 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): # 1. Random starting region: modifies GameStart's exits to point to starting region # 2. DK Portal location rando: modifies entry handler exits to point to randomized portal locations if spoiler: - if region_id == Regions.GameStart and hasattr(settings, 'starting_region') and settings.starting_region: + if region_id == Regions.GameStart and hasattr(settings, "starting_region") and settings.starting_region: region_obj = spoiler.RegionList[Regions.GameStart] elif settings.dk_portal_location_rando_v2 != DKPortalRando.off: # Entry handler regions have their "exit level" transition (exit[1]) modified by DK portal rando @@ -645,7 +645,7 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): } if region_id in entry_handler_regions: region_obj = spoiler.RegionList[region_id] - + for exit in region_obj.exits: destination_name = exit.dest.name @@ -723,10 +723,10 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): if spoiler and settings.starting_region: starting_region_id = settings.starting_region.get("region") starting_region_obj = all_logic_regions.get(starting_region_id) - + if starting_region_obj: starting_level = starting_region_obj.level - + # Map each level to its exit transition level_exit_transitions = { Levels.JungleJapes: Transitions.JapesToIsles, @@ -737,12 +737,12 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): Levels.CrystalCaves: Transitions.CavesToIsles, Levels.CreepyCastle: Transitions.CastleToIsles, } - + # Only create exit level connection for non-Isles levels if starting_level in level_exit_transitions: exit_transition_id = level_exit_transitions[starting_level] - starting_region_name = starting_region_id.name if hasattr(starting_region_id, 'name') else str(starting_region_id) - + starting_region_name = starting_region_id.name if hasattr(starting_region_id, "name") else str(starting_region_id) + # Find the exit transition in the level's entry handler region # Entry handlers have the "exit level" transition defined in their exits level_to_entry_handler = { @@ -754,11 +754,11 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): Levels.CrystalCaves: Regions.CrystalCavesEntryHandler, Levels.CreepyCastle: Regions.CreepyCastleEntryHandler, } - + if starting_level in level_to_entry_handler: entry_handler_region = level_to_entry_handler[starting_level] entry_handler_obj = all_logic_regions.get(entry_handler_region) - + if entry_handler_obj: # Find the exit transition in the entry handler's exits exit_transition = None @@ -766,7 +766,7 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): if exit.exitShuffleId == exit_transition_id: exit_transition = exit break - + # Create connection using the exit transition's logic if exit_transition: target_region_name = exit_transition.dest.name @@ -776,7 +776,7 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): starting_region_name, target_region_name, lambda state, player=world.player, exit=exit_transition: hasDK64RTransition(state, player, exit), - "Exit Level from spawn: " + starting_region_name + "Exit Level from spawn: " + starting_region_name, ) # For tracker regeneration with LZR, also handle deathwarps and exit level connections diff --git a/archipelago/Tracker.py b/archipelago/Tracker.py index 49cad94fc..b721cca13 100644 --- a/archipelago/Tracker.py +++ b/archipelago/Tracker.py @@ -913,4 +913,4 @@ def dk64_map_to_tab_index(data: Any) -> int: "map_page_setting_key": "DK64Rando_{team}_{player}_map", "map_page_index": dk64_map_to_tab_index, "poptracker_name_mapping": poptracker_name_mapping, -} \ No newline at end of file +} diff --git a/randomizer/Patching/MirrorMode.py b/randomizer/Patching/MirrorMode.py index 2d7f8b513..056c32fc8 100644 --- a/randomizer/Patching/MirrorMode.py +++ b/randomizer/Patching/MirrorMode.py @@ -35,12 +35,13 @@ def readDataFromBytestream(data: bytearray, offset: int, size: int, signed: bool value = (1 << (8 * size)) - value return value + def writeValueToBytestream(data: bytearray, value: int, offset: int, size: int) -> bytearray: """Write data to a byte stream.""" values = [0] * size value = int(value) if value < 0: - value += (1 << (size * 8)) + value += 1 << (size * 8) for x in range(size): values[(size - x) - 1] = value & 0xFF value >>= 8 @@ -73,6 +74,7 @@ def ApplyMirrorMode(settings: Settings, ROM_COPY: LocalROM): dl_end = readDataFromBytestream(data, 0x48, 4) FlipDisplayList(ROM_COPY, data, dl_start, dl_end, tbl, file_index) + MISC_SCALES = { 0: 1, # Test Map 29: 1, # Power Shed @@ -87,6 +89,7 @@ def ApplyMirrorMode(settings: Settings, ROM_COPY: LocalROM): 188: 1, # Fungi Blast } + def applyCoordTransform(value: float, map_index: int = 0, apply_scaling: bool = False): """Apply the flipping coordinate transform.""" offset = 3000 @@ -94,6 +97,7 @@ def applyCoordTransform(value: float, map_index: int = 0, apply_scaling: bool = offset *= MISC_SCALES.get(map_index, 3) return offset - value + def ApplyMirrorModeNew(ROM_COPY: LocalROM): """Apply all Mirror Mode changes (testing).""" for map_index in range(216): @@ -176,7 +180,10 @@ def ApplyMirrorModeNew(ROM_COPY: LocalROM): block_end = readDataFromBytestream(file_data, ref, 4) ref += 4 block_count = int((block_end - start) / 0x18) - print(hex(block_end), hex(block_count), ) + print( + hex(block_end), + hex(block_count), + ) for _ in range(block_count): div = coldata["divisor"] for cs in range(3): @@ -207,6 +214,7 @@ def ApplyMirrorModeNew(ROM_COPY: LocalROM): map_exits = writeValueToBytestream(map_exits, new_value, offset, 2) writeRawFile(TableNames.Exits, map_index, False, map_exits, ROM_COPY) + def trimData(data: bytes, alignment: int = 0x10) -> bytes: """Trim a bytes object to remove trailing null bytes, and then align the size of the object to a certain modulo.""" if alignment <= 0: From fff123d811c49aacd8f5219e5a5c9b5c648cc719 Mon Sep 17 00:00:00 2001 From: UmedMuzl Date: Tue, 3 Feb 2026 00:29:22 -0600 Subject: [PATCH 3/7] slot data stuff --- __init__.py | 104 ++++++++++++++++++++++--------- archipelago/DK64Client.py | 24 ------- archipelago/FillSettings.py | 35 ++++++++++- archipelago/Regions.py | 121 ++++++++++++++++++++---------------- archipelago/Tracker.py | 5 +- 5 files changed, 176 insertions(+), 113 deletions(-) diff --git a/__init__.py b/__init__.py index 6312ba2ee..f7f9c875a 100644 --- a/__init__.py +++ b/__init__.py @@ -162,6 +162,7 @@ def copy_dependencies(zip_path, file): from randomizer.Enums.Maps import Maps from randomizer.Enums.Minigames import Minigames from randomizer.Enums.Locations import Locations as DK64RLocations + from randomizer.Enums.Regions import Regions from randomizer.Enums.Settings import ( Enemies, GlitchesSelected, @@ -885,6 +886,42 @@ def _convert_to_cumulative_prices(self, individual_prices, shop_locations, max_c return cumulative_prices + def _restore_custom_location_names(self, custom_location_names: dict): + """Restore custom location names from slot data for UT regeneration.""" + from randomizer.Lists.Location import LocationListOriginal as VanillaLocationList + from archipelago.Regions import BASE_ID + + if not custom_location_names: + return + + print(f"[DK64 UT] Restoring {len(custom_location_names)} custom location names") + + # Build enum_to_index mapping + enum_to_index = {location: index for index, location in enumerate(VanillaLocationList)} + # Build reverse mapping: location_id -> location_enum + index_to_enum = {index: location for location, index in enum_to_index.items()} + + restored_count = 0 + sample_names = [] + for loc_id_str, data in custom_location_names.items(): + loc_id = int(loc_id_str) + # Calculate the enum from the location ID + index = loc_id - BASE_ID + if index in index_to_enum: + location_enum = index_to_enum[index] + if location_enum in self.spoiler.LocationList: + # Restore the custom name + if isinstance(data, dict) and "name" in data: + new_name = data["name"] + self.spoiler.LocationList[location_enum].name = new_name + restored_count += 1 + if restored_count <= 5: + sample_names.append(f" {new_name}") + + print(f"[DK64 UT] Restored {restored_count} names, samples:") + for name in sample_names: + print(name) + def _generate_archipelago_prices(self): """Generate custom shop prices for Archipelago. @@ -1106,6 +1143,10 @@ def generate_early(self): self.spoiler.LocationList[DK64RLocations.FactoryDonkeyDKArcade].name = "Factory Donkey DK Arcade Round 1" self.spoiler.settings.shuffled_location_types.append(Types.ArchipelagoItem) + # For UT regeneration, restore DK portal locations + if hasattr(settings, "ut_dk_portal_locations"): + self.spoiler.human_entry_doors = settings.ut_dk_portal_locations + # Handle custom location shuffling BEFORE regions are created # This needs to happen early so the logic system knows about the new locations from randomizer.Lists.CustomLocations import resetCustomLocations @@ -1115,6 +1156,9 @@ def generate_early(self): resetCustomLocations(self.spoiler) + # Check if this is a UT regeneration + is_ut_regen = hasattr(settings, "ut_custom_location_names") + # Store custom location flags do_crown_shuffle = self.spoiler.settings.crown_placement_rando do_patch_shuffle = self.spoiler.settings.random_patches @@ -1132,21 +1176,23 @@ def generate_early(self): self.spoiler.settings.random_patches = do_patch_shuffle self.spoiler.settings.random_crates = do_crate_shuffle - # Now run custom location shuffles - if do_crown_shuffle: - crown_replacements = {} - crown_human_replacements = {} - ShuffleCrowns(self.spoiler, crown_replacements, crown_human_replacements) - self.spoiler.crown_locations = crown_replacements - self.spoiler.human_crowns = dict(sorted(crown_human_replacements.items())) + # For UT regeneration, skip custom location shuffles (will restore from passthrough later) + if not is_ut_regen: + # Normal generation - run custom location shuffles + if do_crown_shuffle: + crown_replacements = {} + crown_human_replacements = {} + ShuffleCrowns(self.spoiler, crown_replacements, crown_human_replacements) + self.spoiler.crown_locations = crown_replacements + self.spoiler.human_crowns = dict(sorted(crown_human_replacements.items())) - if do_patch_shuffle: - human_patches = {} - self.spoiler.human_patches = ShufflePatches(self.spoiler, human_patches).copy() + if do_patch_shuffle: + human_patches = {} + self.spoiler.human_patches = ShufflePatches(self.spoiler, human_patches).copy() - if do_crate_shuffle: - human_crates = {} - self.spoiler.human_crates = ShuffleMelonCrates(self.spoiler, human_crates).copy() + if do_crate_shuffle: + human_crates = {} + self.spoiler.human_crates = ShuffleMelonCrates(self.spoiler, human_crates).copy() # Store/retrieve blocker values for seed group synchronization if self.options.loading_zone_rando.value not in [0, LoadingZoneRando.option_no]: @@ -1237,6 +1283,13 @@ def generate_early(self): self.spoiler.settings.shuffled_location_types.append(Types.ArchipelagoItem) Generate_Spoiler(self.spoiler) + + # For UT: Restore custom location names after Generate_Spoiler + if hasattr(self.multiworld, "generation_is_fake") and hasattr(self.multiworld, "re_gen_passthrough"): + if "Donkey Kong 64" in self.multiworld.re_gen_passthrough: + passthrough = self.multiworld.re_gen_passthrough["Donkey Kong 64"] + custom_location_names = passthrough.get("CustomLocationNames", {}) + self._restore_custom_location_names(custom_location_names) # Store/retrieve blocker values for seed group synchronization if self.options.loading_zone_rando.value not in [0, LoadingZoneRando.option_no]: @@ -1312,6 +1365,9 @@ def generate_early(self): except (KeyError, AttributeError): print(f"Warning: Could not restore price for location {location_name}") self.spoiler.settings.prices = restored_prices + if passthrough.get("DKPortalLocations") and passthrough["DKPortalLocations"]: + # Restore DK Portal locations + self.spoiler.human_entry_doors = passthrough["DKPortalLocations"] # Handle hint preparation by initiating some variables self.hint_data = { @@ -1927,20 +1983,12 @@ def get_custom_location_names(self) -> dict: custom_location_ids = set(battle_arena_locations) | set(dirt_range) | set(crate_range) - print(f"[DK64 get_custom_location_names] Checking {len(custom_location_ids)} potential custom locations") - # Build a mapping from enum to index in LocationListOriginal enum_to_index = {location: index for index, location in enumerate(VanillaLocationList)} for location_enum in custom_location_ids: if location_enum in self.spoiler.LocationList: location_obj = self.spoiler.LocationList[location_enum] - # Get the vanilla name to compare - vanilla_name = VanillaLocationList[location_enum].name if location_enum in VanillaLocationList else None - - # Debug: Print info about Battle Arena locations - if location_enum in battle_arena_locations: - print(f"[DK64] Battle Arena enum {location_enum}: name='{location_obj.name}', vanilla='{vanilla_name}'") # Include all custom locations, even if names haven't changed # This is necessary because flags can be shuffled even if names stay the same @@ -1948,7 +1996,6 @@ def get_custom_location_names(self) -> dict: # Calculate the AP location ID using the INDEX, not the enum value index = enum_to_index.get(location_enum) if index is None: - print(f"[DK64] WARNING: Could not find index for location enum {location_enum}") continue location_id = BASE_ID + index # Get the flag ID from the location's default_mapid_data @@ -1956,14 +2003,7 @@ def get_custom_location_names(self) -> dict: if location_obj.default_mapid_data and len(location_obj.default_mapid_data) > 0: flag_id = location_obj.default_mapid_data[0].flag custom_locations[location_id] = {"name": location_obj.name, "flag": flag_id} - # Debug: print first few - if len(custom_locations) <= 3: - print(f" Found custom location: {location_obj.name} (ID: {location_id}, Enum: {location_enum}, Index: {index}, Flag: {flag_id}, was: {vanilla_name})") - else: - if location_enum in battle_arena_locations: - print(f"[DK64] WARNING: Battle Arena enum {location_enum} NOT in spoiler.LocationList!") - print(f"[DK64 get_custom_location_names] Found {len(custom_locations)} custom locations total") return custom_locations def fill_slot_data(self) -> dict: @@ -2111,7 +2151,7 @@ def fill_slot_data(self) -> dict: custom_locs = slot_data.get("CustomLocationNames", {}) if custom_locs: print(f"[DK64 Generation] Sending {len(custom_locs)} custom locations in slot_data") - for i, (loc_id, data) in enumerate(list(custom_locs.items())[:3]): + for i, (loc_id, data) in enumerate(list(custom_locs.items())[:5]): if isinstance(data, dict): print(f" Location {loc_id}: {data.get('name')} (flag: {data.get('flag')})") else: @@ -2482,6 +2522,9 @@ def interpret_slot_data(self, slot_data: dict[str, any]) -> dict[str, any]: # Added starting region and DK portal locations starting_region = slot_data.get("StartingRegion", {}) dk_portal_locations = slot_data.get("DKPortalLocations", {}) + + # Custom location names for UT regeneration + custom_location_names = slot_data.get("CustomLocationNames", {}) relevant_data = {} relevant_data["LevelOrder"] = dict(enumerate([Levels[level] for level in level_order], start=1)) @@ -2535,4 +2578,5 @@ def interpret_slot_data(self, slot_data: dict[str, any]) -> dict[str, any]: relevant_data["KongModels"] = kong_models relevant_data["StartingRegion"] = starting_region relevant_data["DKPortalLocations"] = dk_portal_locations + relevant_data["CustomLocationNames"] = custom_location_names return relevant_data diff --git a/archipelago/DK64Client.py b/archipelago/DK64Client.py index d4e7045f2..1ae59ab3d 100644 --- a/archipelago/DK64Client.py +++ b/archipelago/DK64Client.py @@ -1158,12 +1158,10 @@ async def send_checks(self): def update_custom_location_names(self): """Update the check_id_to_name dictionary with custom location names from slot_data.""" custom_location_data = self.slot_data.get("CustomLocationNames", {}) - logger.info(f"CustomLocationNames in slot_data: {len(custom_location_data)} entries") if custom_location_data: # Convert string keys back to integers and extract both name and flag self.custom_check_id_to_name = {} self.custom_check_id_to_flag = {} - self.custom_flag_to_check_id = {} # Reverse mapping for flag -> location ID for id_str, data in custom_location_data.items(): loc_id = int(id_str) if isinstance(data, dict): @@ -1171,8 +1169,6 @@ def update_custom_location_names(self): if data.get("flag") is not None: flag_id = data.get("flag") self.custom_check_id_to_flag[loc_id] = flag_id - # Build reverse mapping: flag_id -> location_id - self.custom_flag_to_check_id[flag_id] = loc_id else: # Backwards compatibility: if data is just a string (old format) self.custom_check_id_to_name[loc_id] = data @@ -1180,12 +1176,10 @@ def update_custom_location_names(self): # Also update the client's dictionaries self.client.custom_check_id_to_name = self.custom_check_id_to_name self.client.custom_check_id_to_flag = self.custom_check_id_to_flag - self.client.custom_flag_to_check_id = self.custom_flag_to_check_id # Update the location_names lookup used by Archipelago's notification system # We need to inject custom names so they take priority over base names if hasattr(self, "location_names") and self.location_names: - logger.info(f"Updating location_names with {len(self.custom_check_id_to_name)} custom location names") try: # Get the game's location store ChainMap if self.game in self.location_names._game_store: @@ -1198,26 +1192,8 @@ def update_custom_location_names(self): # This modifies the ChainMap in place and ensures any existing references see the update updated_chain = game_store.new_child(custom_names_dict) self.location_names._game_store[self.game] = updated_chain - - logger.info(f"Successfully injected {len(custom_names_dict)} custom location names") - - # Verify a few - for loc_id in list(custom_names_dict.keys())[:3]: - verified_name = self.location_names.lookup_in_game(loc_id, self.game) - logger.info(f" Verified location {loc_id}: '{verified_name}'") - else: - logger.warning(f"Game '{self.game}' not found in location_names._game_store") except Exception as e: logger.error(f"Failed to update location_names: {e}", exc_info=True) - else: - logger.warning(f"location_names not available for update") - - logger.info(f"Loaded {len(self.custom_check_id_to_name)} custom location names from slot_data") - logger.info(f"Built reverse mapping with {len(self.custom_flag_to_check_id)} flag->location_id entries") - # Debug: print first few custom locations - for i, (loc_id, name) in enumerate(list(self.custom_check_id_to_name.items())[:3]): - flag = self.custom_check_id_to_flag.get(loc_id) - logger.info(f" Custom location {loc_id}: {name} (flag: {flag})") def event_invalid_slot(self): """Handle an invalid slot event.""" diff --git a/archipelago/FillSettings.py b/archipelago/FillSettings.py index e65e08e9c..31f3a4d40 100644 --- a/archipelago/FillSettings.py +++ b/archipelago/FillSettings.py @@ -314,6 +314,8 @@ def get_default_settings() -> dict: "wrinkly_available": True, "wrinkly_hints": WrinklyHints.standard, "wrinkly_location_rando": False, + "cb_rando_enabled": False, + "cb_rando_list_selected": [], } @@ -357,14 +359,14 @@ def apply_archipelago_settings(settings_dict: dict, options, multiworld) -> None elif options.galleon_water_level == GalleonWaterLevel.option_raised: settings_dict["galleon_water"] = GalleonWaterSetting.raised else: - settings_dict["galleon_water"] = GalleonWaterSetting.vanilla + settings_dict["galleon_water"] = GalleonWaterSetting.lowered settings_dict["no_consumable_upgrades"] = options.remove_bait_potions.value # Custom location settings settings_dict["crown_placement_rando"] = options.crown_placement_rando.value settings_dict["random_crates"] = options.random_crates.value settings_dict["random_patches"] = options.random_patches.value - settings_dict["cb_rando_enabled"] = options.cb_rando_enabled.value + # settings_dict["cb_rando_enabled"] = options.cb_rando_enabled.value def apply_blocker_settings(settings_dict: dict, options) -> None: @@ -906,6 +908,10 @@ def handle_fake_generation_settings(settings: Settings, multiworld) -> None: passthrough = multiworld.re_gen_passthrough["Donkey Kong 64"] settings.level_order = passthrough["LevelOrder"] + # Store custom location names for later restoration (after spoiler is created) + if passthrough.get("CustomLocationNames"): + settings.ut_custom_location_names = passthrough["CustomLocationNames"] + # Switch logic lifted out of level shuffle due to static levels for UT if settings.alter_switch_allocation: for x in range(8): @@ -965,6 +971,31 @@ def handle_fake_generation_settings(settings: Settings, multiworld) -> None: settings.shuffled_location_types.append(Types.Candy) settings.shuffled_location_types.append(Types.Snide) + # Restore starting region + if passthrough.get("StartingRegion"): + from randomizer.Enums.Regions import Regions + from randomizer.Enums.Maps import Maps as DK64Maps + + starting_region_data = passthrough["StartingRegion"] + # Ensure all fields exist and are not None + if all(key in starting_region_data and starting_region_data[key] is not None + for key in ["region", "map", "exit", "region_name", "exit_name"]): + try: + settings.starting_region = { + "region": Regions[starting_region_data["region"]], + "map": DK64Maps[starting_region_data["map"]], + "exit": starting_region_data["exit"], + "region_name": starting_region_data["region_name"], + "exit_name": starting_region_data["exit_name"], + } + except (KeyError, TypeError) as e: + # If there's an error converting the data, just skip it + pass + + # Store DK Portal locations for later restoration (after spoiler is created) + if passthrough.get("DKPortalLocations"): + settings.ut_dk_portal_locations = passthrough["DKPortalLocations"] + def fillsettings(options, multiworld, random_obj): """Fill and configure all DK64 settings.""" diff --git a/archipelago/Regions.py b/archipelago/Regions.py index bc1fa3e1a..93fe1fae9 100644 --- a/archipelago/Regions.py +++ b/archipelago/Regions.py @@ -116,6 +116,13 @@ def create_regions(multiworld: MultiWorld, player: int, spoiler: Spoiler, option spoiler.LocationList[location].name: (BASE_ID + index) for index, location in enumerate(DK64RLocation.LocationListOriginal) if spoiler.LocationList[location].type != Types.EnemyPhoto } all_locations_dynamic.update({"Victory": 0x00}) # Temp for generating goal location + + # Debug: check for custom location names + custom_names = [name for name in all_locations_dynamic.keys() if "Battle Arena" in name or "Melon Crate" in name or "Dirt:" in name] + if custom_names and len(custom_names) > 0: + print(f"[DK64 create_regions] Found {len(custom_names)} custom locations, samples:") + for name in custom_names[:5]: + print(f" {name}") # Pick random 10 shops to make shared # Only if shared shops are enabled in settings @@ -720,64 +727,68 @@ def connect_regions(world: World, settings: Settings, spoiler: Spoiler = None): # Random Starting Region: Create "exit level" connection from spawn point # When spawning in a level, you can use the "Exit Level" menu option to return to the lobby. # This connection uses the actual exit transition logic (not free) to respect entrance rando. - if spoiler and settings.starting_region: + if spoiler and hasattr(settings, "starting_region") and settings.starting_region: starting_region_id = settings.starting_region.get("region") - starting_region_obj = all_logic_regions.get(starting_region_id) - - if starting_region_obj: - starting_level = starting_region_obj.level - - # Map each level to its exit transition - level_exit_transitions = { - Levels.JungleJapes: Transitions.JapesToIsles, - Levels.AngryAztec: Transitions.AztecToIsles, - Levels.FranticFactory: Transitions.FactoryToIsles, - Levels.GloomyGalleon: Transitions.GalleonToIsles, - Levels.FungiForest: Transitions.ForestToIsles, - Levels.CrystalCaves: Transitions.CavesToIsles, - Levels.CreepyCastle: Transitions.CastleToIsles, - } - - # Only create exit level connection for non-Isles levels - if starting_level in level_exit_transitions: - exit_transition_id = level_exit_transitions[starting_level] - starting_region_name = starting_region_id.name if hasattr(starting_region_id, "name") else str(starting_region_id) - - # Find the exit transition in the level's entry handler region - # Entry handlers have the "exit level" transition defined in their exits - level_to_entry_handler = { - Levels.JungleJapes: Regions.JungleJapesEntryHandler, - Levels.AngryAztec: Regions.AngryAztecEntryHandler, - Levels.FranticFactory: Regions.FranticFactoryEntryHandler, - Levels.GloomyGalleon: Regions.GloomyGalleonEntryHandler, - Levels.FungiForest: Regions.FungiForestEntryHandler, - Levels.CrystalCaves: Regions.CrystalCavesEntryHandler, - Levels.CreepyCastle: Regions.CreepyCastleEntryHandler, + if starting_region_id is None: + # starting_region dict exists but is empty or missing region key + pass + else: + starting_region_obj = all_logic_regions.get(starting_region_id) + + if starting_region_obj: + starting_level = starting_region_obj.level + + # Map each level to its exit transition + level_exit_transitions = { + Levels.JungleJapes: Transitions.JapesToIsles, + Levels.AngryAztec: Transitions.AztecToIsles, + Levels.FranticFactory: Transitions.FactoryToIsles, + Levels.GloomyGalleon: Transitions.GalleonToIsles, + Levels.FungiForest: Transitions.ForestToIsles, + Levels.CrystalCaves: Transitions.CavesToIsles, + Levels.CreepyCastle: Transitions.CastleToIsles, } - if starting_level in level_to_entry_handler: - entry_handler_region = level_to_entry_handler[starting_level] - entry_handler_obj = all_logic_regions.get(entry_handler_region) - - if entry_handler_obj: - # Find the exit transition in the entry handler's exits - exit_transition = None - for exit in entry_handler_obj.exits: - if exit.exitShuffleId == exit_transition_id: - exit_transition = exit - break - - # Create connection using the exit transition's logic - if exit_transition: - target_region_name = exit_transition.dest.name - # Use the actual transition logic (respects entrance rando and logic requirements) - connect( - world, - starting_region_name, - target_region_name, - lambda state, player=world.player, exit=exit_transition: hasDK64RTransition(state, player, exit), - "Exit Level from spawn: " + starting_region_name, - ) + # Only create exit level connection for non-Isles levels + if starting_level in level_exit_transitions: + exit_transition_id = level_exit_transitions[starting_level] + starting_region_name = starting_region_id.name if hasattr(starting_region_id, "name") else str(starting_region_id) + + # Find the exit transition in the level's entry handler region + # Entry handlers have the "exit level" transition defined in their exits + level_to_entry_handler = { + Levels.JungleJapes: Regions.JungleJapesEntryHandler, + Levels.AngryAztec: Regions.AngryAztecEntryHandler, + Levels.FranticFactory: Regions.FranticFactoryEntryHandler, + Levels.GloomyGalleon: Regions.GloomyGalleonEntryHandler, + Levels.FungiForest: Regions.FungiForestEntryHandler, + Levels.CrystalCaves: Regions.CrystalCavesEntryHandler, + Levels.CreepyCastle: Regions.CreepyCastleEntryHandler, + } + + if starting_level in level_to_entry_handler: + entry_handler_region = level_to_entry_handler[starting_level] + entry_handler_obj = all_logic_regions.get(entry_handler_region) + + if entry_handler_obj: + # Find the exit transition in the entry handler's exits + exit_transition = None + for exit in entry_handler_obj.exits: + if exit.exitShuffleId == exit_transition_id: + exit_transition = exit + break + + # Create connection using the exit transition's logic + if exit_transition: + target_region_name = exit_transition.dest.name + # Use the actual transition logic (respects entrance rando and logic requirements) + connect( + world, + starting_region_name, + target_region_name, + lambda state, player=world.player, exit=exit_transition: hasDK64RTransition(state, player, exit), + "Exit Level from spawn: " + starting_region_name, + ) # For tracker regeneration with LZR, also handle deathwarps and exit level connections if pairings: diff --git a/archipelago/Tracker.py b/archipelago/Tracker.py index b721cca13..7044972c2 100644 --- a/archipelago/Tracker.py +++ b/archipelago/Tracker.py @@ -4,8 +4,9 @@ def dk64_map_to_tab_index(data: Any) -> int: - # TODO: Make a map mapping for UT - pass + """Map DK64 data to a tab index for the tracker.""" + # TODO: Implement proper map mapping for UT when map tabs are needed + return -1 # PopTracker section name to Archipelago location ID mapping From 0f54289fe439c1fc52436bf4e7c24e45d6879c4b Mon Sep 17 00:00:00 2001 From: UmedMuzl Date: Tue, 3 Feb 2026 23:35:41 -0600 Subject: [PATCH 4/7] logic fix --- randomizer/Lists/CustomLocations.py | 18 +++--------------- randomizer/LogicFiles/AngryAztec.py | 2 +- randomizer/LogicFiles/CrystalCaves.py | 2 +- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/randomizer/Lists/CustomLocations.py b/randomizer/Lists/CustomLocations.py index d463d75d9..ba32763ba 100644 --- a/randomizer/Lists/CustomLocations.py +++ b/randomizer/Lists/CustomLocations.py @@ -1572,7 +1572,7 @@ class LocationTypes(IntEnum): z=2385, max_size=64, logic_region=Regions.LlamaTemple, - logic=lambda l: Events.AztecLlamaSpit in l.Events and l.HasGun(Kongs.any) and l.swim and l.scope and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or (not l.istiny)), + logic=lambda l: Events.AztecLlamaSpit in l.Events and l.HasGun(Kongs.any) and l.swim and l.scope and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or l.isdonkey or l.isdiddy or l.islanky or l.ischunky), group=4, banned_types=[LocationTypes.CrownPad, LocationTypes.DirtPatch, LocationTypes.Bananaport], ), @@ -3855,7 +3855,7 @@ class LocationTypes(IntEnum): max_size=64, logic_region=Regions.IglooArea, group=3, - logic=lambda l: (l.HasGun(Kongs.any) and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or (not l.istiny))) or l.Slam, + logic=lambda l: (l.HasGun(Kongs.any) and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or l.isdonkey or l.isdiddy or l.islanky or l.ischunky)) or l.Slam, banned_types=[LocationTypes.CrownPad, LocationTypes.DirtPatch, LocationTypes.Bananaport], ), CustomLocation( @@ -6123,22 +6123,10 @@ class LocationTypes(IntEnum): z=1159, max_size=64, logic_region=Regions.TrainingGrounds, - logic=lambda l: l.HasGun(Kongs.any) and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or (not l.istiny)) and l.swim and l.scope, + logic=lambda l: l.HasGun(Kongs.any) and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or l.isdonkey or l.isdiddy or l.islanky or l.ischunky) and l.swim and l.scope, group=3, banned_types=[LocationTypes.CrownPad, LocationTypes.DirtPatch], ), - # CustomLocation( - # map=Maps.TrainingGrounds, - # name="Training Grounds: Under Water in Corner", - # x=1962, - # y=-187, - # z=1324, - # max_size=64, - # logic_region=Regions.TrainingGrounds, - # logic=lambda l: l.HasGun(Kongs.any) and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or (not l.istiny)) and l.swim and l.scope, - # group=2, - # banned_types=[LocationTypes.CrownPad, LocationTypes.DirtPatch], - # ), CustomLocation( map=Maps.TrainingGrounds, name="Training Grounds: Near Pool", diff --git a/randomizer/LogicFiles/AngryAztec.py b/randomizer/LogicFiles/AngryAztec.py index c70ab56db..358b6a7a7 100644 --- a/randomizer/LogicFiles/AngryAztec.py +++ b/randomizer/LogicFiles/AngryAztec.py @@ -210,7 +210,7 @@ TransitionFront(Regions.TinyTempleEntrance, lambda l: (Events.FedTotem in l.Events and l.feather and l.istiny) or l.CanPhase(), Transitions.AztecMainToTiny), TransitionFront(Regions.ChunkyTempleEntrance, lambda l: (Events.FedTotem in l.Events and l.pineapple and l.ischunky) or l.CanPhase() or (l.generalclips and l.ischunky and l.hunkyChunky), Transitions.AztecMainToChunky), TransitionFront(Regions.AztecTinyRace, lambda l: l.charge and l.jetpack and l.diddy and l.mini and l.saxophone and l.istiny, Transitions.AztecMainToRace), - TransitionFront(Regions.LlamaTemple, lambda l: l.canOpenLlamaTemple() or l.CanPhase() or (l.generalclips and not l.islanky), Transitions.AztecMainToLlama), + TransitionFront(Regions.LlamaTemple, lambda l: l.canOpenLlamaTemple() or l.CanPhase() or (l.generalclips and l.isdonkey or l.isdiddy or l.istiny or l.ischunky), Transitions.AztecMainToLlama), TransitionFront(Regions.AztecBaboonBlast, lambda l: l.blast and l.isdonkey), # , Transitions.AztecMainToBBlast), TransitionFront(Regions.Snide, lambda l: l.snideAccess), TransitionFront(Regions.FunkyAztec, lambda l: l.funkyAccess), diff --git a/randomizer/LogicFiles/CrystalCaves.py b/randomizer/LogicFiles/CrystalCaves.py index 871dbfc64..cc5e5855e 100644 --- a/randomizer/LogicFiles/CrystalCaves.py +++ b/randomizer/LogicFiles/CrystalCaves.py @@ -138,7 +138,7 @@ ), Regions.FrozenCastle: Region("Frozen Castle", HintRegion.MainCaves, Levels.CrystalCaves, False, None, [ - LocationLogic(Locations.CavesLankyCastle, lambda l: l.Slam and (l.islanky or (l.settings.free_trade_items and (not l.isdonkey or l.superSlam)))), + LocationLogic(Locations.CavesLankyCastle, lambda l: l.Slam and (l.islanky or (l.settings.free_trade_items and (l.isdiddy or l.istiny or l.ischunky or l.superSlam)))), LocationLogic(Locations.KremKap_CavesNPC_IceTomato, lambda l: l.camera), ], [], [ TransitionFront(Regions.CrystalCavesMain, lambda _: True, Transitions.CavesCastleToMain), From 0469b0c3c311b922ff82a91fe07e524db039ec80 Mon Sep 17 00:00:00 2001 From: UmedMuzl Date: Sun, 8 Feb 2026 22:03:09 -0600 Subject: [PATCH 5/7] Complete --- __init__.py | 100 ++- archipelago/Regions.py | 3 + archipelago/Tracker.py | 1691 +++++++++++++++++++++------------------- 3 files changed, 979 insertions(+), 815 deletions(-) diff --git a/__init__.py b/__init__.py index bab76152c..112843de6 100644 --- a/__init__.py +++ b/__init__.py @@ -1156,13 +1156,15 @@ def generate_early(self): resetCustomLocations(self.spoiler) - # Check if this is a UT regeneration - is_ut_regen = hasattr(settings, "ut_custom_location_names") + # Check if this is a UT regeneration - use generation_is_fake flag + is_ut_regen = hasattr(self.multiworld, "generation_is_fake") + print(f"[DK64] Is UT regen: {is_ut_regen}, has generation_is_fake: {hasattr(self.multiworld, 'generation_is_fake')}") # Store custom location flags do_crown_shuffle = self.spoiler.settings.crown_placement_rando do_patch_shuffle = self.spoiler.settings.random_patches do_crate_shuffle = self.spoiler.settings.random_crates + print(f"[DK64] Shuffle flags - Crowns: {do_crown_shuffle}, Patches: {do_patch_shuffle}, Crates: {do_crate_shuffle}") # Temporarily disable custom locations so Generate_Spoiler doesn't run them self.spoiler.settings.crown_placement_rando = False @@ -1175,8 +1177,7 @@ def generate_early(self): self.spoiler.settings.crown_placement_rando = do_crown_shuffle self.spoiler.settings.random_patches = do_patch_shuffle self.spoiler.settings.random_crates = do_crate_shuffle - - # For UT regeneration, skip custom location shuffles (will restore from passthrough later) + if not is_ut_regen: # Normal generation - run custom location shuffles if do_crown_shuffle: @@ -1185,14 +1186,17 @@ def generate_early(self): ShuffleCrowns(self.spoiler, crown_replacements, crown_human_replacements) self.spoiler.crown_locations = crown_replacements self.spoiler.human_crowns = dict(sorted(crown_human_replacements.items())) + print(f"[DK64] Shuffled {len([c for crowns in crown_replacements.values() for c in crowns])} battle arenas") if do_patch_shuffle: human_patches = {} self.spoiler.human_patches = ShufflePatches(self.spoiler, human_patches).copy() + print(f"[DK64] Shuffled {len(self.spoiler.dirt_patch_placement)} dirt patches") if do_crate_shuffle: human_crates = {} self.spoiler.human_crates = ShuffleMelonCrates(self.spoiler, human_crates).copy() + print(f"[DK64] Shuffled {len(self.spoiler.meloncrate_placement)} melon crates") # Store/retrieve blocker values for seed group synchronization if self.options.loading_zone_rando.value not in [0, LoadingZoneRando.option_no]: @@ -1345,6 +1349,8 @@ def generate_early(self): if hasattr(self.multiworld, "re_gen_passthrough"): if "Donkey Kong 64" in self.multiworld.re_gen_passthrough: passthrough = self.multiworld.re_gen_passthrough["Donkey Kong 64"] + + # Restore enemy, minigame, shop, and portal data if passthrough["EnemyData"]: for location, data in passthrough["EnemyData"].items(): self.spoiler.enemy_location_list[DK64RLocations[location]] = EnemyLoc(Maps[data["map"]], Enemies[data["enemy"]], 0, [], False) @@ -1368,6 +1374,61 @@ def generate_early(self): if passthrough.get("DKPortalLocations") and passthrough["DKPortalLocations"]: # Restore DK Portal locations self.spoiler.human_entry_doors = passthrough["DKPortalLocations"] + + # Update entry handler region exits to point to the restored DK Portal locations + # This matches the behavior in DoorData.assignDKPortal() + from randomizer.Enums.Levels import Levels + from randomizer.Lists.DoorLocations import door_locations, LEVEL_ENTRY_HANDLER_REGIONS + from randomizer.LogicClasses import TransitionFront + + level_name_to_enum = { + "Jungle Japes": Levels.JungleJapes, + "Angry Aztec": Levels.AngryAztec, + "Frantic Factory": Levels.FranticFactory, + "Gloomy Galleon": Levels.GloomyGalleon, + "Fungi Forest": Levels.FungiForest, + "Crystal Caves": Levels.CrystalCaves, + "Creepy Castle": Levels.CreepyCastle, + } + + for level_name, door_name in self.spoiler.human_entry_doors.items(): + if door_name != "Vanilla": + level_enum = level_name_to_enum.get(level_name) + if level_enum is not None: + # Find the door with this name in the door_locations list + for door_data in door_locations[level_enum]: + if door_data.name == door_name: + # Update the entry handler region's exit to point to this door's logic region + placement_region = LEVEL_ENTRY_HANDLER_REGIONS[level_enum] + self.spoiler.RegionList[placement_region].exits[1] = TransitionFront( + door_data.logicregion, lambda _: True + ) + break + + # Restore entrance randomization connections for yamlless generation + if passthrough.get("EntranceRando") and passthrough["EntranceRando"]: + # Store entrance connections for later restoration + # These will be applied in connect_entrances when we detect yamlless generation + self.saved_entrance_connections = passthrough["EntranceRando"] + + # Restore starting region for yamlless generation + if passthrough.get("StartingRegion") and passthrough["StartingRegion"]: + from randomizer.Enums.Regions import Regions + from randomizer.Enums.Maps import Maps + + starting_region_data = passthrough["StartingRegion"] + # Reconstruct the starting_region dictionary + self.spoiler.settings.starting_region = { + "region": Regions[starting_region_data["region"]], + "map": Maps[starting_region_data["map"]], + "exit": starting_region_data["exit"], + "region_name": starting_region_data["region_name"], + "exit_name": starting_region_data["exit_name"], + } + # Update GameStart region exits to point to the restored starting region + # This matches the behavior in Settings.RandomizeStartingLocation() + for x in range(2): + self.spoiler.RegionList[Regions.GameStart].exits[x + 1].dest = self.spoiler.settings.starting_region["region"] # Handle hint preparation by initiating some variables self.hint_data = { @@ -1408,6 +1469,12 @@ def exclude_locations(location_names: typing.List[str]): # Exclude the locations using Archipelago's exclude_locations mechanism if excluded_locations: exclude_locations(excluded_locations) + + # AFTER all regions are created, restore custom location shuffles for UT + # This must happen here (not in generate_early) to override default placements + if hasattr(self.multiworld, "generation_is_fake") and hasattr(self.multiworld, "re_gen_passthrough"): + if "Donkey Kong 64" in self.multiworld.re_gen_passthrough: + self._restore_shuffled_custom_locations() def create_items(self) -> None: """Create the items.""" @@ -2008,6 +2075,18 @@ def get_custom_location_names(self) -> dict: def fill_slot_data(self) -> dict: """Fill the slot data.""" + # Debug: Check if shuffle attributes exist + print(f"[DK64 fill_slot_data START] Checking spoiler attributes:") + print(f" has crown_locations: {hasattr(self.spoiler, 'crown_locations')}") + print(f" has dirt_patch_placement: {hasattr(self.spoiler, 'dirt_patch_placement')}") + print(f" has meloncrate_placement: {hasattr(self.spoiler, 'meloncrate_placement')}") + if hasattr(self.spoiler, 'crown_locations'): + print(f" crown_locations length: {len(self.spoiler.crown_locations) if self.spoiler.crown_locations else 0}") + if hasattr(self.spoiler, 'dirt_patch_placement'): + print(f" dirt_patch_placement length: {len(self.spoiler.dirt_patch_placement) if self.spoiler.dirt_patch_placement else 0}") + if hasattr(self.spoiler, 'meloncrate_placement'): + print(f" meloncrate_placement length: {len(self.spoiler.meloncrate_placement) if self.spoiler.meloncrate_placement else 0}") + # If hints are enabled, wait for hint compilation to complete if hasattr(self, "options") and self.options.hint_style > 0: self.hint_compilation_complete.wait() @@ -2433,8 +2512,6 @@ def interpret_slot_data(self, slot_data: dict[str, any]) -> dict[str, any]: """Parse slot data for any logical bits that need to match the real generation. Used by Universal Tracker.""" # Parse the string data version = slot_data["Version"] - if version != self.ap_version: - print(f"Version mismatch: {version} != {self.ap_version}. You may experience unexpected behavior.") level_order = slot_data["LevelOrder"].split(", ") starting_kongs = slot_data["StartingKongs"].split(", ") @@ -2525,6 +2602,11 @@ def interpret_slot_data(self, slot_data: dict[str, any]) -> dict[str, any]: # Custom location names for UT regeneration custom_location_names = slot_data.get("CustomLocationNames", {}) + + # Custom location shuffle data for UT regeneration + crown_shuffle_data = slot_data.get("CrownShuffleData", None) + patch_shuffle_data = slot_data.get("PatchShuffleData", None) + crate_shuffle_data = slot_data.get("CrateShuffleData", None) relevant_data = {} relevant_data["LevelOrder"] = dict(enumerate([Levels[level] for level in level_order], start=1)) @@ -2579,4 +2661,10 @@ def interpret_slot_data(self, slot_data: dict[str, any]) -> dict[str, any]: relevant_data["StartingRegion"] = starting_region relevant_data["DKPortalLocations"] = dk_portal_locations relevant_data["CustomLocationNames"] = custom_location_names + if crown_shuffle_data is not None: + relevant_data["CrownShuffleData"] = crown_shuffle_data + if patch_shuffle_data is not None: + relevant_data["PatchShuffleData"] = patch_shuffle_data + if crate_shuffle_data is not None: + relevant_data["CrateShuffleData"] = crate_shuffle_data return relevant_data diff --git a/archipelago/Regions.py b/archipelago/Regions.py index 93fe1fae9..313fc8839 100644 --- a/archipelago/Regions.py +++ b/archipelago/Regions.py @@ -235,6 +235,9 @@ def create_region( # Dropsanity would otherwise flood the world with irrelevant locked locations, greatly slowing seed gen if location_obj.type == Types.Enemies and Types.Enemies not in logic_holder.settings.shuffled_location_types: continue + # Skip boulder/holdable items if not shuffled + if location_obj.type == Types.BoulderItem and Types.BoulderItem not in logic_holder.settings.shuffled_location_types: + continue # Skip shared shops that are not in the available pool if location_obj.type == Types.Shop and location_obj.kong == Kongs.any: if location_logic.id not in logic_holder.available_shared_shops: diff --git a/archipelago/Tracker.py b/archipelago/Tracker.py index 7044972c2..369980230 100644 --- a/archipelago/Tracker.py +++ b/archipelago/Tracker.py @@ -4,545 +4,851 @@ def dk64_map_to_tab_index(data: Any) -> int: - """Map DK64 data to a tab index for the tracker.""" - # TODO: Implement proper map mapping for UT when map tabs are needed - return -1 + """Map DK64 game map ID to flat sub-area index for UT navigation. + + Returns the flat index across ALL sub-areas in map_page_groups. + """ + # Handle empty or None data + if data is None or data == "" or data == b"": + return 0 + + # Convert to int if needed + try: + if isinstance(data, str): + data = data.strip() + if not data: + return 0 + map_id = int(data) if not isinstance(data, int) else data + except (ValueError, TypeError): + return 0 + + map_to_flat_index = { + # DK Isles (indices 0-10) + 34: 0, 189: 0, 97: 0, # isles + 176: 1, 171: 1, # training + 169: 2, # japeslobby + 173: 3, # azteclobby + 175: 4, # factorylobby + 174: 5, # galleonlobby + 178: 6, # forestlobby + 194: 7, # caveslobby + 193: 8, # castlelobby + 170: 9, # helmlobby + 195: 10, # snidelobby + 203: 0, 204: 0, 205: 0, 206: 0, 207: 0, 214: 0, # K. Rool phases -> isles + 15: 10, # Snide's -> snidelobby + # Jungle Japes (indices 11-14) + 7: 11, 12: 11, 13: 11, 37: 11, # japes main area (beehive, painting room, blast) + 33: 12, # japesunder + 4: 13, 6: 13, # japesmountain (includes minecarts) + # shellhive (14) - no specific map ID, part of main japes + # Angry Aztec (indices 15-22) + 38: 15, 14: 15, 41: 15, # aztec main area + 16: 16, # tinytemple + 20: 17, # llamatemple + 19: 18, # dk5dt + 21: 19, # diddy5dt + 23: 20, # lanky5dt + 22: 21, # tiny5dt + 24: 22, # chunky5dt + # Frantic Factory (index 23) + 26: 23, 27: 23, 29: 23, 36: 23, 110: 23, # factory + # Gloomy Galleon (index 24) + 30: 24, 49: 24, 45: 24, 31: 24, 39: 24, 44: 24, 179: 24, # galleon + 51: 24, 46: 24, 43: 24, 47: 24, 54: 24, + # Fungi Forest (indices 25-28) + 48: 25, 55: 25, 64: 25, 71: 25, 70: 25, 63: 25, 52: 25, # forest main + 56: 25, 57: 25, 58: 25, 188: 25, + 61: 26, # frontmill + 62: 27, 60: 27, # rearmill + 59: 28, # barn + # Crystal Caves (index 29) + 72: 29, 82: 29, 98: 29, 86: 29, 100: 29, 85: 29, 84: 29, # caves + 95: 29, 89: 29, 91: 29, 92: 29, 200: 29, 94: 29, 93: 29, 90: 29, 186: 29, + # Creepy Castle (indices 30-36) + 87: 30, 164: 30, 114: 30, 105: 30, 168: 30, 167: 30, 166: 30, 187: 30, # castle exterior + 151: 31, # dungeontunnel + 163: 32, # dungeon + 183: 33, 108: 33, # crypthub + 112: 34, 106: 34, # crypt + 88: 35, # ballroom + 113: 36, 185: 36, # museum + # Hideout Helm (index 37) + 17: 37, # helm + } + + flat_index = map_to_flat_index.get(map_id, 0) + return flat_index # PopTracker section name to Archipelago location ID mapping # Format: "Parent/Section Name": location_id # Auto-generated from location_mapping.lua (837 locations total) poptracker_name_mapping = { - "Medals/Aztec DK Medal": 14041209, + "Japes Lobby Entrance/Isles Japes Lobby Entrance Item": 14041140, + "Tiny Feather Cage/Isles Tiny Feather Cage": 14041141, + "Upper Krem Isles/Isles Tiny Saxophone Pad": 14041142, + "Isles Lanky Grape Cage/Isles Lanky Grape Cage": 14041143, + "Chunky Pineapple Cage/Isles Chunky Pineapple Cage": 14041144, + "Isles Chunky Triangle Pad/Isles Chunky Triangle Pad": 14041145, + "Chunky Pound the X/Isles Chunky Pound the X": 14041146, + "Isles Fairy (Small Island)/Isles Fairy (Small Island)": 14041147, + "Upper Krem Isles/Isles Fairy (Upper Krem Isles)": 14041148, + "K. Lumsy Prison/Isles Lanky Sprint Cage": 14041149, + "Banana Fairy Island/The Banana Fairy's Gift": 14041150, + "Banana Fairy Island/Returning the Banana Fairies": 14041151, + "Isles Lanky Instrument Pad/Isles Lanky Japes Instrument": 14041152, + "Isles Tiny Aztec Lobby Barrel/Isles Tiny Aztec Lobby Barrel": 14041153, + "Isles DK Coconut Cage/Isles Donkey Coconut Cage": 14041154, + "Isles Diddy Snide Barrel/Isles Diddy Snides Spring Barrel": 14041155, + "Isles Battle Arena 1/Isles Battle Arena 1 (Snide's Room: Under Rock)": 14041156, + "Isles DK Bongo Pad/Isles Donkey Bongos Pad": 14041157, + "Isles Factory Lobby Box/Isles Kasplat: Factory Lobby Box": 14041158, + "Isles Factory Lobby Box/Isles Fairy (Factory Lobby)": 14041159, + "Isles Tiny Galleon Lobby Swim/Isles Tiny Galleon Lobby Swim": 14041160, + "Isles Kasplat: Galleon Lobby/Isles Kasplat: Galleon Lobby": 14041161, + "Isles Diddy Peanut Cage/Isles Diddy Peanut Cage": 14041162, + "Isles Diddy Summit Barrel/Isles Diddy Summit Barrel": 14041163, + "Isles Battle Arena 2 (Fungi Lobby)/Isles Battle Arena 2 (Fungi Lobby: Gorilla Gone Box)": 14041164, + "Isles Fairy (Fungi Lobby)/Isles Fairy (Forest Lobby)": 14041165, + "Isles DK Caves Lava/Isles Donkey Caves Lava": 14041166, + "Isles Diddy Guitar Pad/Isles Diddy Guitar Pad": 14041167, + "Isles Kasplat: Caves Lobby Punch/Isles Kasplat: Caves Lobby Punch": 14041168, + "Upper Castle Lobby/Isles Lanky Castle Lobby Barrel": 14041169, + "Isles Kasplat: Castle Lobby/Isles Kasplat: Castle Lobby": 14041170, + "Isles Chunky Helm Lobby Barrel/Isles Chunky Helm Lobby Barrel": 14041171, + "Isles Kasplat: Helm Lobby/Isles Kasplat: Helm Lobby": 14041172, + "Medals/Japes Donkey Medal": 14041174, + "Medals/Japes Diddy Medal": 14041175, + "Medals/Japes Lanky Medal": 14041176, + "Medals/Japes Tiny Medal": 14041177, + "Medals/Japes Chunky Medal": 14041178, + "Diddy Cage/Japes Cage: Diddy Kong": 14041179, + "Diddy Cage/Japes in Front of Diddy Cage": 14041180, + "Diddy Cage/Japes Free Diddy Item": 14041181, + "Japes DK Floor Cage Banana/Japes Donkey Floor Cage Banana": 14041182, + "Japes DK Baboon Blast/Japes Donkey Baboon Blast": 14041183, + "Japes Diddy Timed Cage Banana/Japes Diddy Timed Cage Banana": 14041184, + "Japes Diddy Top of Mountain/Japes Diddy Top of Mountain": 14041185, + "Japes Lanky Timed Cage Banana/Japes Lanky Timed Cage Banana": 14041186, + "Japes Tiny Timed Cage Banana/Japes Tiny Timed Cage Banana": 14041187, + "Japes Chunky Boulder/Japes Chunky Boulder": 14041188, + "Japes Chunky Timed Cage Banana/Japes Chunky Timed Cage Banana": 14041189, + "Japes Battle Arena (Near Funky)/Japes Battle Arena (Near Funky)": 14041190, + "Japes Diddy Peanut Tunnel/Japes Diddy Peanut Tunnel": 14041191, + "Japes Lanky Grape Gate Barrel/Japes Lanky Grape Gate Barrel": 14041192, + "Japes Tiny Feather Gate Barrel/Japes Tiny Feather Gate Barrel": 14041193, + "Japes Kasplat: Hive Tunnel Lower/Japes Kasplat: Hive Tunnel Lower": 14041194, + "Japes Kasplat: Hive Tunnel Upper/Japes Kasplat: Hive Tunnel Upper": 14041195, + "Japes Tiny Stump/Japes Tiny Stump": 14041196, + "Japes Chunky Giant Bonus Barrel/Japes Chunky Giant Bonus Barrel": 14041197, + "Japes Tiny Beehive/Japes Tiny Beehive": 14041198, + "Japes Lanky Slope Barrel/Japes Lanky Slope Barrel": 14041199, + "Japes Kasplat: Near Painting Room/Japes Kasplat: Near Painting Room": 14041200, + "Japes Kasplat: By Lanky Slope Bonus/Japes Kasplat: By Lanky Slope Bonus": 14041201, + "Japes Fairy (Rambi Door Pool)/Japes Fairy (Rambi Door Pool)": 14041202, + "Painting Room/Japes Lanky Painting Room Zingers": 14041203, + "Painting Room/Japes Fairy (Painting Room)": 14041204, + "Japes Diddy Minecart/Japes Diddy Minecart": 14041205, + "Japes Chunky Underground/Japes Chunky Underground": 14041206, + "Japes Kasplat: Underground/Japes Kasplat: Underground": 14041207, + "Medals/Japes Boss Defeated": 14041208, + "Medals/Aztec Donkey Medal": 14041209, "Medals/Aztec Diddy Medal": 14041210, "Medals/Aztec Lanky Medal": 14041211, "Medals/Aztec Tiny Medal": 14041212, "Medals/Aztec Chunky Medal": 14041213, - "Medals/Aztec DK Half-Medal": 14042334, - "Medals/Aztec Diddy Half-Medal": 14042335, - "Medals/Aztec Lanky Half-Medal": 14042336, - "Medals/Aztec Tiny Half-Medal": 14042337, - "Medals/Aztec Chunky Half-Medal": 14042338, - "Medals/Boss": 14041244, - "Aztec Chunky Vases/Golden Banana": 14041215, - "Aztec Kasplat: Behind DK Stone Door/Kasplat": 14041216, - "Aztec DK Free Llama Blast/Golden Banana": 14041214, - "Aztec Kasplat: On Tiny Temple/Kasplat": 14041217, - "Aztec Dirt: Oasis/Rainbow Coin": 14041679, - "Aztec Chunky Klaptrap Room/Golden Banana": 14041219, - "Aztec Tiny Klaptrap Room/Golden Banana": 14041218, - "Aztec Lanky Vulture Shooting/Golden Banana": 14041222, - "Aztec Battle Arena (Tiny Temple: Vulture Room)/Crown": 14041223, - "Tiny's Cage/Tiny Kong's Cage": 14041220, + "Aztec DK Free Llama Blast/Aztec Donkey Free Llama Blast": 14041214, + "Aztec Chunky Vases/Aztec Chunky Vases": 14041215, + "Aztec Kasplat: Behind DK Stone Door/Aztec Kasplat: Behind DK Stone Door": 14041216, + "Aztec Kasplat: On Tiny Temple/Aztec Kasplat: On Tiny Temple": 14041217, + "Aztec Tiny Klaptrap Room/Aztec Tiny Klaptrap Room": 14041218, + "Aztec Chunky Klaptrap Room/Aztec Chunky Klaptrap Room": 14041219, + "Tiny's Cage/Aztec Cage: Tiny Kong": 14041220, "Tiny's Cage/Aztec Free Tiny Item": 14041221, - "Aztec Chunky Giant Caged Barrel/Golden Banana": 14041227, - "Aztec Kasplat: Hunky Chunky Barrel/Kasplat": 14041228, - "Aztec Diddy Ram Gongs/Golden Banana": 14041225, - "Aztec Diddy Vulture Race/Golden Banana": 14041226, - "Aztec Crate: On Llama Temple/Crate": 14041695, - "Aztec Crate: Near Gong Tower/Crate": 14041696, - "Aztec DK Sealed Quicksand Tunnel Barrel/Golden Banana": 14041224, - "5 Door Temple/Aztec DK 5DT": 14041229, - "5 Door Temple/Aztec Diddy 5DT": 14041230, - "5 Door Temple/Aztec Lanky 5DT": 14041231, - "5 Door Temple/Aztec Tiny 5DT": 14041232, - "5 Door Temple/Aztec Fairy (Inside Tiny 5DT)": 14041233, - "5 Door Temple/Aztec Chunky 5DT": 14041234, - "5 Door Temple/Aztec Kasplat: Chunky 5DT": 14041235, - "5 Door Temple/Aztec Dirt: Chunky 5DT": 14041674, - "Aztec Tiny Beetle Race/Golden Banana": 14041236, - "Lanky's Cage/Lanky Kong's Cage": 14041237, + "Aztec Lanky Vulture Shooting/Aztec Lanky Vulture Shooting": 14041222, + "Aztec Battle Arena (Tiny Temple: Vulture Room)/Aztec Battle Arena (Tiny Temple: Vulture Room)": 14041223, + "Aztec DK Sealed Quicksand Tunnel Barrel/Aztec Donkey Sealed Quicksand Tunnel Barrel": 14041224, + "Aztec Diddy Ram Gongs/Aztec Diddy Ram Gongs": 14041225, + "Aztec Diddy Vulture Race/Aztec Diddy Vulture Race": 14041226, + "Aztec Chunky Giant Caged Barrel/Aztec Chunky Giant Caged Barrel": 14041227, + "Aztec Kasplat: Hunky Chunky Barrel/Aztec Kasplat: Hunky Chunky Barrel": 14041228, + "5 Door Temple/Aztec Donkey 5 Door Temple": 14041229, + "5 Door Temple/Aztec Diddy 5 Door Temple": 14041230, + "5 Door Temple/Aztec Lanky 5 Door Temple": 14041231, + "5 Door Temple/Aztec Tiny 5 Door Temple": 14041232, + "5 Door Temple/Aztec Fairy (Tiny 5-Door Temple)": 14041233, + "5 Door Temple/Aztec Chunky 5 Door Temple": 14041234, + "5 Door Temple/Aztec Kasplat: Chunky 5-Door Temple": 14041235, + "Aztec Tiny Beetle Race/Aztec Tiny Beetle Race": 14041236, + "Lanky's Cage/Aztec Cage: Lanky Kong": 14041237, "Lanky's Cage/Aztec Free Lanky Item": 14041238, - "Aztec Lanky Llama Temple Barrel/Golden Banana": 14041239, - "Aztec Fairy (Llama Temple)/Fairy": 14041241, - "Aztec Crate: Llama Temple/Crate": 14041691, - "Aztec Lanky Matching Game/Golden Banana": 14041240, - "Aztec Tiny Llama Temple Lava Pedestals/Golden Banana": 14041242, - "Aztec Kasplat: Llama Temple Lava/Kasplat": 14041243, - "Medals/Castle DK Medal": 14041389, - "Medals/Castle Diddy Medal": 14041390, - "Medals/Castle Lanky Medal": 14041391, - "Medals/Castle Tiny Medal": 14041392, - "Medals/Castle Chunky Medal": 14041393, - "Medals/Castle DK Half-Medal": 14042359, - "Medals/Castle Diddy Half-Medal": 14042360, - "Medals/Castle Lanky Half-Medal": 14042361, - "Medals/Castle Tiny Half-Medal": 14042362, - "Medals/Castle Chunky Half-Medal": 14042363, - "Medals/Boss": 14041422, - "Castle Diddy Above Castle/Golden Banana": 14041394, - "Castle Kasplat: Near Upper Warp 2/Kasplat": 14041395, - "Castle Dirt: Top Floor/Rainbow Coin": 14041684, - "Castle Kasplat: On a Lone Platform/Kasplat": 14041396, - "Inside the Tree/Castle DK Tree Sniping": 14041397, - "Inside the Tree/Castle Kasplat: Inside the Tree": 14041399, - "Inside the Tree/Castle Fairy (Tree Sniping Room)": 14041400, - "Inside the Tree/Castle Chunky Tree Sniping Barrel": 14041398, - "Castle DK Library/Golden Banana": 14041401, - "Castle Diddy Ballroom/Golden Banana": 14041402, - "Castle Fairy (Near Car Race)/Fairy": 14041403, - "Castle Tiny Car Race/Golden Banana": 14041404, - "Castle Lanky Tower/Golden Banana": 14041405, - "Greenhouse/Castle Lanky Greenhouse": 14041406, - "Greenhouse/Castle Battle Arena (Greenhouse Center)": 14041407, - "Castle Tiny Trashcan/Golden Banana": 14041408, - "Castle Chunky Shed/Golden Banana": 14041409, - "Castle Chunky Museum/Golden Banana": 14041410, - "Castle Kasplat: Lower Cave Center/Kasplat": 14041411, - "Castle Crate: Behind Mausoleum Entrance/Crate": 14041701, - "Castle Diddy Crypt/Golden Banana": 14041412, - "Castle Chunky Crypt/Golden Banana": 14041413, - "Castle DK Minecart/Golden Banana": 14041414, - "Mausoleum/Castle Lanky Mausoleum": 14041415, - "Mausoleum/Castle Tiny Mausoleum": 14041416, - "Castle Tiny Over Chasm/Golden Banana": 14041417, - "Castle Kasplat: Near Candy's/Kasplat": 14041418, - "Castle DK Dungeon/Golden Banana": 14041419, - "Castle Diddy Dungeon/Golden Banana": 14041420, - "Castle Lanky Dungeon/Golden Banana": 14041421, - "Medals/Caves DK Medal": 14041355, - "Medals/Caves Diddy Medal": 14041356, - "Medals/Caves Lanky Medal": 14041357, - "Medals/Caves Tiny Medal": 14041358, - "Medals/Caves Chunky Medal": 14041359, - "Medals/Caves DK Half-Medal": 14042354, - "Medals/Caves Diddy Half-Medal": 14042355, - "Medals/Caves Lanky Half-Medal": 14042356, - "Medals/Caves Tiny Half-Medal": 14042357, - "Medals/Caves Chunky Half-Medal": 14042358, - "Medals/Boss": 14041388, - "Caves Diddy Jetpack Barrel/Golden Banana": 14041361, - "Caves Kasplat: Near Ice Castle/Kasplat": 14041365, - "Caves Chunky Gorilla Gone/Golden Banana": 14041364, - "Caves Kasplat: Mini Room by Funky/Kasplat": 14041366, - "Caves Tiny Mini Cave Barrel/Golden Banana": 14041362, - "Caves Kasplat: On the Pillar/Kasplat": 14041367, - "Caves DK Baboon Blast/Golden Banana": 14041360, - "Caves Lanky Beetle Race/Golden Banana": 14041369, - "Caves Lanky Ice Castle Slam Challenge/Golden Banana": 14041370, - "Caves Tiny Monkeyport Igloo/Golden Banana": 14041363, - "Caves Chunky Transparent Igloo/Golden Banana": 14041371, - "Caves Kasplat: On 5-Door Igloo/Kasplat": 14041372, - "Caves Dirt: Giant Kosha/Rainbow Coin": 14041683, - "Caves DK 5 Door Igloo/Golden Banana": 14041373, - "Caves Diddy 5 Door Igloo/Golden Banana": 14041374, - "Caves Lanky 5 Door Igloo/Golden Banana": 14041375, - "Caves Tiny 5 Door Igloo/Golden Banana": 14041376, - "Caves Tiny 5 Door Igloo/Fairy": 14041377, - "Caves Chunky 5 Door Igloo/Golden Banana": 14041378, - "Caves Kasplat: By the Far Warp 2/Kasplat": 14041368, - "Rotating Cabin/Caves DK Rotating Cabin": 14041379, - "Rotating Cabin/Caves Battle Arena": 14041380, - "Caves DK 5 Door Cabin/Golden Banana": 14041381, - "Caves Diddy 5 Door Cabin Lower/Golden Banana": 14041382, - "Caves Diddy 5 Door Cabin Upper/Golden Banana": 14041383, - "Caves Diddy 5 Door Cabin Upper/Fairy": 14041384, - "Caves Lanky Sprint Cabin/Golden Banana": 14041385, - "Caves Tiny 5 Door Cabin/Golden Banana": 14041386, - "Caves Chunky 5 Door Cabin/Golden Banana": 14041387, - "Isles Dirt: Training Grounds Rear Tunnel/Rainbow Coin": 14041686, - "Isles Dirt: Banana Hoard/Rainbow Coin": 14041687, - "Japes Lobby Entrance/Golden Banana": 14041140, - "Chunky Pineapple Cage/Golden Banana": 14041144, - "Tiny Feather Cage/Golden Banana": 14041141, - "Chunky Pound the X/Golden Banana": 14041146, - "Isles Fairy (Small Island)/Fairy": 14041147, - "Isles Dirt: Under Caves Lobby/Rainbow Coin": 14041677, - "Isles Chunky Triangle Pad/Golden Banana": 14041145, - "K. Lumsy Prison/Isles Lanky Sprint Cage": 14041149, - "K. Lumsy Prison/Isles Dirt: Back of Prison": 14041685, - "Banana Fairy Island/The Banana Fairy's Gift": 14041150, - "Banana Fairy Island/Returning the Banana Fairies": 14041151, - "Isles Lanky Instrument Pad/Golden Banana": 14041152, - "Japes DK Wrinkly Door/Wrinkly Door": 14041603, - "Japes Diddy Wrinkly Door/Wrinkly Door": 14041604, - "Japes Lanky Wrinkly Door/Wrinkly Door": 14041605, - "Japes Tiny Wrinkly Door/Wrinkly Door": 14041606, - "Japes Chunky Wrinkly Door/Wrinkly Door": 14041607, - "Isles Tiny Aztec Lobby Barrel/Golden Banana": 14041153, - "Aztec DK Wrinkly Door/Wrinkly Door": 14041608, - "Aztec Diddy Wrinkly Door/Wrinkly Door": 14041609, - "Aztec Lanky Wrinkly Door/Wrinkly Door": 14041610, - "Aztec Tiny Wrinkly Door/Wrinkly Door": 14041611, - "Aztec Chunky Wrinkly Door/Wrinkly Door": 14041612, - "Isles Lanky Grape Cage/Golden Banana": 14041143, - "Isles DK Coconut Cage/Golden Banana": 14041154, - "Upper Krem Isles/Isles Tiny Saxophone Pad": 14041142, - "Upper Krem Isles/Isles Fairy (Upper Krem Isle)": 14041148, - "Isles Diddy Snide Barrel/Golden Banana": 14041155, - "Isles Battle Arena 1/Crown": 14041156, - "Isles DK Bongo Pad/Golden Banana": 14041157, - "Isles Factory Lobby Box/Kasplat": 14041158, - "Isles Factory Lobby Box/Isles Fairy (Factory Lobby)": 14041159, - "Factory DK Wrinkly Door/Wrinkly Door": 14041613, - "Factory Diddy Wrinkly Door/Wrinkly Door": 14041614, - "Factory Lanky Wrinkly Door/Wrinkly Door": 14041615, - "Factory Tiny Wrinkly Door/Wrinkly Door": 14041616, - "Factory Chunky Wrinkly Door/Wrinkly Door": 14041617, - "Isles Tiny Galleon Lobby Swim/Golden Banana": 14041160, - "Isles Kasplat: Galleon Lobby/Kasplat": 14041161, - "Galleon DK Hint Door/Wrinkly Door": 14041618, - "Galleon Diddy Hint Door/Wrinkly Door": 14041619, - "Galleon Lanky Hint Door/Wrinkly Door": 14041620, - "Galleon Tiny Hint Door/Wrinkly Door": 14041621, - "Galleon Chunky Hint Door/Wrinkly Door": 14041622, - "Isles Dirt: Cabin Isle/Rainbow Coin": 14041676, - "Isles Diddy Peanut Cage/Golden Banana": 14041162, - "Isles Diddy Summit Barrel/Golden Banana": 14041163, - "Isles Dirt: Aztec Roof/Rainbow Coin": 14041678, - "Isles Battle Arena 2 (Fungi Lobby)/Crown": 14041164, - "Isles Fairy (Fungi Lobby)/Fairy": 14041165, - "Forest DK Hint Door/Wrinkly Door": 14041623, - "Forest Diddy Hint Door/Wrinkly Door": 14041624, - "Forest Lanky Hint Door/Wrinkly Door": 14041625, - "Forest Tiny Hint Door/Wrinkly Door": 14041626, - "Forest Chunky Hint Door/Wrinkly Door": 14041627, - "Isles DK Caves Lava/Golden Banana": 14041166, - "Isles Diddy Guitar Pad/Golden Banana": 14041167, - "Isles Kasplat: Caves Lobby Punch/Kasplat": 14041168, - "Caves DK Hint Door/Wrinkly Door": 14041628, - "Caves Diddy Hint Door/Wrinkly Door": 14041629, - "Caves Lanky Hint Door/Wrinkly Door": 14041630, - "Caves Tiny Hint Door/Wrinkly Door": 14041631, - "Caves Chunky Hint Door/Wrinkly Door": 14041632, - "Upper Castle Lobby/Isles Lanky Castle Lobby Barrel": 14041169, - "Isles Kasplat: Castle Lobby/Kasplat": 14041170, - "Castle DK Hint Door/Wrinkly Door": 14041633, - "Castle Diddy Hint Door/Wrinkly Door": 14041634, - "Castle Lanky Hint Door/Wrinkly Door": 14041635, - "Castle Tiny Hint Door/Wrinkly Door": 14041636, - "Castle Chunky Hint Door/Wrinkly Door": 14041637, - "Upper Castle Lobby/Isles Dirt: Castle Lobby": 14041688, - "Isles Chunky Helm Lobby Barrel/Golden Banana": 14041171, - "Isles Kasplat: Helm Lobby/Kasplat": 14041172, - "Medals/Forest DK Medal": 14041320, + "Aztec Lanky Llama Temple Barrel/Aztec Lanky Llama Temple Barrel": 14041239, + "Aztec Lanky Matching Game/Aztec Lanky Matching Game": 14041240, + "Aztec Fairy (Llama Temple)/Aztec Fairy (Llama Temple)": 14041241, + "Aztec Tiny Llama Temple Lava Pedestals/Aztec Tiny Llama Temple Lava Pedestals": 14041242, + "Aztec Kasplat: Llama Temple Lava/Aztec Kasplat: Llama Temple Lava": 14041243, + "Medals/Aztec Boss Defeated": 14041244, + "Medals/Factory Donkey Medal": 14041245, + "Medals/Factory Diddy Medal": 14041246, + "Medals/Factory Lanky Medal": 14041247, + "Medals/Factory Tiny Medal": 14041248, + "Medals/Factory Chunky Medal": 14041249, + "Factory DK Number Game/Factory Donkey Number Game": 14041250, + "Factory Diddy Block Tower/Factory Diddy Block Tower": 14041251, + "Factory Lanky Testing Room Barrel/Factory Lanky Testing Room Barrel": 14041252, + "Factory Tiny Dartboard/Factory Tiny Dartboard": 14041253, + "Factory Kasplat: Block Tower/Factory Kasplat: Block Tower": 14041254, + "Factory Fairy (Number Game)/Factory Fairy (Number Game)": 14041255, + "Factory Fairy (Near Funky's)/Factory Fairy (Near Funky's)": 14041256, + "Factory Diddy Charge Enemies/Factory Diddy Charge Enemies": 14041257, + "Factory Lanky Piano Game/Factory Lanky Piano Game": 14041258, + "Factory Chunky Toy Monster/Factory Chunky Toy Monster": 14041259, + "Factory Kasplat: R&D/Factory Kasplat: Research and Development": 14041260, + "Factory Battle Arena (Under Grate)/Factory Battle Arena (Under R&D Grate)": 14041261, + "Factory Tiny Car Race/Factory Tiny Car Race": 14041262, + "Factory Diddy Storage Room Barrel/Factory Diddy Storage Room Barrel": 14041263, + "Factory DK Power Hut/Factory Donkey Power Hut": 14041264, + "Chunky's Cage/Factory Cage: Chunky Kong": 14041265, + "DK Arcade/DK Arcade Round 2": 14041266, + "Factory DK Blast Course/Factory Donkey DK Arcade Round 1": 14041267, + "Chunky's Cage/Factory Free Chunky Item": 14041268, + "Factory Tiny Mini by Arcade/Factory Tiny Mini by Arcade": 14041269, + "Factory Chunky Dark Room/Factory Chunky Dark Room": 14041270, + "Factory Chunky Barrel by Arcade/Factory Chunky Barrel by Arcade": 14041271, + "Factory Kasplat: Base of Production/Factory Kasplat: Base of Production": 14041272, + "Factory Kasplat: Pole to Arcade/Factory Kasplat: Pole to Arcade": 14041273, + "Factory DK Crusher Room/Factory Donkey Crusher Room": 14041274, + "Factory Diddy Production Spring/Factory Diddy Production Spring": 14041275, + "Factory Lanky Production Handstand/Factory Lanky Production Handstand": 14041276, + "Factory Tiny Production Twirl/Factory Tiny Production Twirl": 14041277, + "Factory Chunky Production Timer/Factory Chunky Production Timer": 14041278, + "Factory Kasplat: Upper Production Pipe/Factory Kasplat: Upper Production Pipe": 14041279, + "Medals/Factory Boss Defeated": 14041280, + "Medals/Galleon Donkey Medal": 14041281, + "Medals/Galleon Diddy Medal": 14041282, + "Medals/Galleon Lanky Medal": 14041283, + "Medals/Galleon Tiny Medal": 14041284, + "Medals/Galleon Chunky Medal": 14041285, + "Galleon Chunky Chest/Galleon Chunky Chest": 14041286, + "Galleon Kasplat: Past Vines/Galleon Kasplat: Past Vines": 14041287, + "Galleon Battle Arena (Under Cranky)/Galleon Battle Arena (Under Cranky)": 14041288, + "Galleon Fairy (In Punch Chest)/Galleon Fairy (In Punch Chest)": 14041289, + "Galleon Chunky Cannon Game/Galleon Chunky Cannon Game": 14041290, + "Galleon Kasplat: Cannon Game Room/Galleon Kasplat: Cannon Game Room": 14041291, + "Galleon Diddy Top of Lighthouse/Galleon Diddy Top of Lighthouse": 14041292, + "Galleon Lanky Enguarde Chest/Galleon Lanky Enguarde Chest": 14041293, + "Galleon Kasplat: Lighthouse Alcove/Galleon Kasplat: Lighthouse Alcove": 14041294, + "Lighthouse/Galleon Donkey Lighthouse": 14041295, + "Galleon Tiny Mermaid Reward/Galleon Tiny Mermaid Reward": 14041296, + "Galleon Chunky Seasick/Galleon Chunky Seasick": 14041297, + "Galleon Seal/Galleon Donkey Free the Seal": 14041298, + "Galleon Kasplat: Musical Cactus/Galleon Kasplat: Musical Cactus": 14041299, + "Galleon Seal/Galleon Donkey Seal Race": 14041300, + "Galleon Diddy Gold Tower Barrel/Galleon Diddy Gold Tower Barrel": 14041301, + "Galleon Lanky Gold Tower Barrel/Galleon Lanky Gold Tower Barrel": 14041302, + "Galleon Kasplat: Diddy Gold Tower/Galleon Kasplat: Diddy Gold Tower": 14041303, + "Galleon Tiny Submarine Barrel/Galleon Tiny Submarine Barrel": 14041304, + "Galleon Diddy Mechfish/Galleon Diddy Mechfish": 14041305, + "2-Door Ship/Galleon Lanky 2 Door Ship": 14041306, + "2-Door Ship/Galleon Tiny 2 Door Ship": 14041307, + "Galleon DK 5-Door Ship/Galleon Donkey 5 Door Ship": 14041308, + "Galleon Diddy 5-Door Ship/Galleon Diddy 5 Door Ship": 14041309, + "Galleon Lanky 5-Door Ship/Galleon Lanky 5 Door Ship": 14041310, + "Galleon Tiny 5-Door Ship/Galleon Tiny 5 Door Ship": 14041311, + "Galleon Tiny 5-Door Ship/Galleon Fairy (In Tiny's 5-Door Ship)": 14041312, + "Galleon Chunky 5-Door Ship/Galleon Chunky 5 Door Ship": 14041313, + "Treasure Chest/Treasure Chest Far Left Clam": 14041314, + "Treasure Chest/Treasure Chest Center Clam": 14041315, + "Treasure Chest/Treasure Chest Far Right Clam": 14041316, + "Treasure Chest/Treasure Chest Close Right Clam": 14041317, + "Treasure Chest/Treasure Chest Close Left Clam": 14041318, + "Medals/Galleon Boss Defeated": 14041319, + "Medals/Forest Donkey Medal": 14041320, "Medals/Forest Diddy Medal": 14041321, "Medals/Forest Lanky Medal": 14041322, "Medals/Forest Tiny Medal": 14041323, "Medals/Forest Chunky Medal": 14041324, - "Medals/Forest DK Half-Medal": 14042349, - "Medals/Forest Diddy Half-Medal": 14042350, - "Medals/Forest Lanky Half-Medal": 14042351, - "Medals/Forest Tiny Half-Medal": 14042352, - "Medals/Forest Chunky Half-Medal": 14042353, - "Medals/Boss": 14041354, - "Forest Chunky Minecart/Golden Banana": 14041325, - "Forest Diddy Top of Mushroom Barrel/Golden Banana": 14041326, + "Forest Chunky Minecart/Forest Chunky Minecart": 14041325, + "Forest Diddy Top of Mushroom Barrel/Forest Diddy Top of Mushroom Barrel": 14041326, "Inside the Mushroom/Forest Tiny Mushroom Barrel": 14041327, - "Forest Kasplat: Lower Mushroom Exterior/Kasplat": 14041329, - "Forest DK Baboon Blast/Golden Banana": 14041328, + "Forest DK Baboon Blast/Forest Donkey Baboon Blast": 14041328, + "Forest Kasplat: Lower Mushroom Exterior/Forest Kasplat: Low Mushroom Exterior": 14041329, + "Inside the Mushroom/Forest Donkey Mushroom Cannons": 14041330, "Inside the Mushroom/Forest Kasplat: Inside Giant Mushroom": 14041331, - "Inside the Mushroom/Forest DK Mushroom Cannons": 14041330, - "Forest Kasplat: Mushroom Night Door/Kasplat": 14041332, - "Forest Battle Arena: High Ladder Platform/Crown": 14041333, + "Forest Kasplat: Mushroom Night Door/Forest Kasplat: Mushroom Night Door": 14041332, + "Forest Battle Arena: High Ladder Platform/Forest Battle Arena (Giant Mushroom High Ladder Platform)": 14041333, "Face Puzzle Room/Forest Chunky Face Puzzle": 14041334, - "Zinger Room/Forest Lanky Zinger Room": 14041335, - "Forest Lanky Coloured Mushroom Slam/Golden Banana": 14041336, - "Forest Diddy Owl Race/Golden Banana": 14041337, - "Forest Lanky Rabbit Race/Golden Banana": 14041338, - "Forest Kasplat: Under Owl Tree/Kasplat": 14041339, - "Forest Crate: Near Owl Tree/Crate": 14041697, + "Zinger Room/Forest Lanky Zinger Bounce": 14041335, + "Forest Lanky Coloured Mushroom Slam/Forest Lanky Colored Mushroom Slam": 14041336, + "Forest Diddy Owl Race/Forest Diddy Owl Race": 14041337, + "Forest Lanky Rabbit Race/Forest Lanky Rabbit Race": 14041338, + "Forest Kasplat: Under Owl Tree/Forest Kasplat: Under Owl Tree": 14041339, "Forest Anthill/Forest Tiny Anthill Banana": 14041340, - "Forest Anthill/Forest Tiny Bean": 14041353, - "Forest DK Mill Levers/Golden Banana": 14041341, + "Forest DK Mill Levers/Forest Donkey Mill Levers": 14041341, "Winch Room/Forest Diddy Winch Cage": 14041342, - "Forest Dirt: Near Mills Grass/Rainbow Coin": 14041680, - "Forest Crate: Behind Dark Attic/Crate": 14041699, - "Forest Tiny Spider Boss/Golden Banana": 14041343, - "Forest Chunky Keg Crushing/Golden Banana": 14041344, + "Forest Tiny Spider Boss/Forest Tiny Spider Boss": 14041343, + "Forest Chunky Keg Crushing/Forest Chunky Keg Crushing": 14041344, "Dark Rafters/Forest Diddy Dark Rafters": 14041345, "Dark Rafters/Forest Fairy (Dark Rafters)": 14041346, - "Forest Lanky Attic Shooting/Golden Banana": 14041347, - "Forest Kasplat: Behind DK's Barn/Kasplat": 14041348, - "Forest Crate: Near Thornvine Barn/Crate": 14041698, - "Forest Donkey Thornvine Barn Barrel/Golden Banana": 14041349, - "Forest Crate: In Thornvine Barn/Crate": 14041700, - "Forest Fairy (Thornvine Barn)/Fairy": 14041350, - "Forest Tiny Top of Beanstalk/Golden Banana": 14041351, - "Forest Chunky Apple Rescue/Golden Banana": 14041352, - "Forest Dirt: Beanstalk/Rainbow Coin": 14041681, - "Helm Battle Arena/Crown": 14041433, - "Helm DK Medal/Medal": 14041434, - "Helm Chunky Medal/Medal": 14041435, - "Helm Tiny Medal/Medal": 14041436, - "Helm Lanky Medal/Medal": 14041437, - "Helm Diddy Medal/Medal": 14041438, - "The End of Helm/Key": 14041441, - "Helm Fairy (Key 8 Room)/Fairy 1": 14041439, - "Helm Fairy (Key 8 Room)/Fairy 2": 14041440, - "Medals/Japes DK Medal": 14041174, - "Medals/Japes Diddy Medal": 14041175, - "Medals/Japes Lanky Medal": 14041176, - "Medals/Japes Tiny Medal": 14041177, - "Medals/Japes Chunky Medal": 14041178, - "Medals/Japes DK Half-Medal": 14042329, - "Medals/Japes Diddy Half-Medal": 14042330, - "Medals/Japes Lanky Half-Medal": 14042331, - "Medals/Japes Tiny Half-Medal": 14042332, - "Medals/Japes Chunky Half-Medal": 14042333, - "Medals/Boss": 14041208, - "Japes DK Floor Cage Banana/Golden Banana": 14041182, - "Japes Chunky Boulder/Golden Banana": 14041188, - "Japes Lanky Timed Cage Banana/Golden Banana": 14041186, - "Diddy Cage/Diddy Kong's Cage": 14041179, - "Diddy Cage/Japes in Front of Diddy Cage": 14041180, - "Diddy Cage/Japes Free Diddy Item": 14041181, - "Japes Crate: Behind the Mountain/Crate": 14041689, - "Japes Chunky Timed Cage Banana/Golden Banana": 14041189, - "Japes Diddy Timed Cage Banana/Golden Banana": 14041184, - "Japes Battle Arena (Near Funky)/Crown": 14041190, - "Japes Tiny Timed Cage Banana/Golden Banana": 14041187, - "Japes Dirt: Painting Hill/Rainbow Coin": 14041673, - "Japes Diddy Top of Mountain/Golden Banana": 14041185, - "Japes DK Baboon Blast/Golden Banana": 14041183, - "Japes Diddy Peanut Tunnel/Golden Banana": 14041191, - "Japes Lanky Grape Gate Barrel/Golden Banana": 14041192, - "Japes Tiny Feather Gate Barrel/Golden Banana": 14041193, - "Japes Kasplat: Hive Tunnel Lower/Kasplat": 14041194, - "Japes Kasplat: Hive Tunnel Upper/Kasplat": 14041195, - "Japes Tiny Stump/Golden Banana": 14041196, - "Japes Chunky Giant Bonus Barrel/Golden Banana": 14041197, - "Japes Tiny Beehive/Golden Banana": 14041198, - "Japes Lanky Slope Barrel/Golden Banana": 14041199, - "Japes Kasplat: Near Painting Room/Kasplat": 14041200, - "Japes Kasplat: By Lanky Slope Bonus/Kasplat": 14041201, - "Japes Fairy (Rambi Door Pool)/Fairy": 14041202, - "Japes Crate: In the Rambi Cave/Crate": 14041690, - "Painting Room/Japes Lanky Zingers": 14041203, - "Painting Room/Japes Fairy (Painting Room)": 14041204, - "Japes Diddy Minecart/Golden Banana": 14041205, - "Japes Chunky Underground/Golden Banana": 14041206, - "Japes Kasplat: Underground/Kasplat": 14041207, - "Jungle Japes Enemy: Start/Enemy": 14041718, - "Jungle Japes Enemy: Diddy Cavern/Enemy": 14041719, - "Jungle Japes Enemy: Tunnel (0)/Enemy": 14041720, - "Jungle Japes Enemy: Tunnel (1)/Enemy": 14041721, - "Jungle Japes Enemy: Storm (0)/Enemy": 14041722, - "Jungle Japes Enemy: Storm (1)/Enemy": 14041723, - "Jungle Japes Enemy: Storm (2)/Enemy": 14041724, - "Jungle Japes Enemy: Hive (0)/Enemy": 14041725, - "Jungle Japes Enemy: Hive (1)/Enemy": 14041726, - "Jungle Japes Enemy: Hive (2)/Enemy": 14041727, - "Jungle Japes Enemy: Hive (3)/Enemy": 14041728, - "Jungle Japes Enemy: Hive (4)/Enemy": 14041729, - "Jungle Japes Enemy: Killed In Demo/Enemy": 14041730, - "Jungle Japes Enemy: Near Underground/Enemy": 14041731, - "Jungle Japes Enemy: Near Painting (0)/Enemy": 14041732, - "Jungle Japes Enemy: Near Painting (1)/Enemy": 14041733, - "Jungle Japes Enemy: Near Painting (2)/Enemy": 14041734, - "Jungle Japes Enemy: Mountain/Enemy": 14041735, - "Jungle Japes Enemy: Feather Tunnel/Enemy": 14041736, - "Jungle Japes Enemy: Middle Tunnel/Enemy": 14041737, - "Japes Mountain Enemy: Start (0)/Enemy": 14041740, - "Japes Mountain Enemy: Start (1)/Enemy": 14041741, - "Japes Mountain Enemy: Start (2)/Enemy": 14041742, - "Japes Mountain Enemy: Start (3)/Enemy": 14041743, - "Japes Mountain Enemy: Start (4)/Enemy": 14041744, - "Japes Mountain Enemy: Near Gate Switch (0)/Enemy": 14041745, - "Japes Mountain Enemy: Near Gate Switch (1)/Enemy": 14041746, - "Japes Mountain Enemy: Hi Lo/Enemy": 14041747, - "Japes Mountain Enemy: Conveyor (0)/Enemy": 14041748, - "Japes Mountain Enemy: Conveyor (1)/Enemy": 14041749, - "Japes Tiny Hive Enemy: First Room/Enemy": 14041750, - "Japes Tiny Hive Enemy: Second Room (0)/Enemy": 14041751, - "Japes Tiny Hive Enemy: Second Room (1)/Enemy": 14041752, - "Japes Tiny Hive Enemy: Third Room (0)/Enemy": 14041753, - "Japes Tiny Hive Enemy: Third Room (1)/Enemy": 14041754, - "Japes Tiny Hive Enemy: Third Room (2)/Enemy": 14041755, - "Japes Tiny Hive Enemy: Third Room (3)/Enemy": 14041756, - "Japes Tiny Hive Enemy: Main Room/Enemy": 14041757, - "Angry Aztec Enemy: Vase Room (0)/Enemy": 14041758, - "Angry Aztec Enemy: Vase Room (1)/Enemy": 14041759, - "Angry Aztec Enemy: Vase Room (2)/Enemy": 14041760, - "Angry Aztec Enemy: Tunnel Pad (0)/Enemy": 14041761, - "Angry Aztec Enemy: Tunnel Cage (0)/Enemy": 14041762, - "Angry Aztec Enemy: Tunnel Cage (1)/Enemy": 14041763, - "Angry Aztec Enemy: Tunnel Cage (2)/Enemy": 14041764, - "Angry Aztec Enemy: Starting Tunnel (0)/Enemy": 14041765, - "Angry Aztec Enemy: Starting Tunnel (1)/Enemy": 14041766, - "Angry Aztec Enemy: Oasis Door/Enemy": 14041767, - "Angry Aztec Enemy: Tunnel Cage (3)/Enemy": 14041768, - "Angry Aztec Enemy: Outside Llama/Enemy": 14041769, - "Angry Aztec Enemy: Outside Tower/Enemy": 14041770, - "Angry Aztec Enemy: Tunnel Pad (1)/Enemy": 14041771, - "Angry Aztec Enemy: Near Candy/Enemy": 14041772, - "Angry Aztec Enemy: Around Totem/Enemy": 14041773, - "Angry Aztec Enemy: Starting Tunnel (2)/Enemy": 14041774, - "Angry Aztec Enemy: Starting Tunnel (3)/Enemy": 14041775, - "Angry Aztec Enemy: Outside Snide/Enemy": 14041776, - "Angry Aztec Enemy: Outside 5DT/Enemy": 14041777, - "Angry Aztec Enemy: Near Sealed Quicksand Tunnel/Enemy": 14041778, - "Aztec Donkey 5DTemple Enemy: Start Trap (0)/Enemy": 14041779, - "Aztec Donkey 5DTemple Enemy: Start Trap (1)/Enemy": 14041780, - "Aztec Donkey 5DTemple Enemy: Start Trap (2)/Enemy": 14041781, - "Aztec Donkey 5DTemple Enemy: End Trap (0)/Enemy": 14041782, - "Aztec Donkey 5DTemple Enemy: End Trap (1)/Enemy": 14041783, - "Aztec Donkey 5DTemple Enemy: End Trap (2)/Enemy": 14041784, - "Aztec Donkey 5DTemple Enemy: End Path (0)/Enemy": 14041785, - "Aztec Donkey 5DTemple Enemy: End Path (1)/Enemy": 14041786, - "Aztec Donkey 5DTemple Enemy: Start Path/Enemy": 14041787, - "Aztec Diddy 5DTemple Enemy: End Trap (0)/Enemy": 14041788, - "Aztec Diddy 5DTemple Enemy: End Trap (1)/Enemy": 14041789, - "Aztec Diddy 5DTemple Enemy: End Trap (2)/Enemy": 14041790, - "Aztec Diddy 5DTemple Enemy: Start Left (0)/Enemy": 14041791, - "Aztec Diddy 5DTemple Enemy: Start Left (1)/Enemy": 14041792, - "Aztec Diddy 5DTemple Enemy: Reward/Enemy": 14041793, - "Aztec Diddy 5DTemple Enemy: Second Switch/Enemy": 14041794, - "Aztec Lanky 5DTemple Enemy: Joining Paths/Enemy": 14041795, - "Aztec Lanky 5DTemple Enemy: End Trap/Enemy": 14041796, - "Aztec Lanky 5DTemple Enemy: Reward/Enemy": 14041797, - "Aztec Tiny 5DTemple Enemy: Start Right Front/Enemy": 14041798, - "Aztec Tiny 5DTemple Enemy: Start Left Back/Enemy": 14041799, - "Aztec Tiny 5DTemple Enemy: Start Right Back/Enemy": 14041800, - "Aztec Tiny 5DTemple Enemy: Start Left Front/Enemy": 14041801, - "Aztec Tiny 5DTemple Enemy: Reward (0)/Enemy": 14041802, - "Aztec Tiny 5DTemple Enemy: Reward (1)/Enemy": 14041803, - "Aztec Tiny 5DTemple Enemy: Dead End (0)/Enemy": 14041804, - "Aztec Tiny 5DTemple Enemy: Dead End (1)/Enemy": 14041805, - "Aztec Chunky 5DTemple Enemy: Start Right/Enemy": 14041806, - "Aztec Chunky 5DTemple Enemy: Start Left/Enemy": 14041807, - "Aztec Chunky 5DTemple Enemy: Second Right/Enemy": 14041808, - "Aztec Chunky 5DTemple Enemy: Second Left/Enemy": 14041809, - "Aztec Chunky 5DTemple Enemy: Reward/Enemy": 14041810, - "Aztec Llama Temple Enemy: Kong Free Instrument/Enemy": 14041811, - "Aztec Llama Temple Enemy: Dino Instrument/Enemy": 14041812, - "Aztec Llama Temple Enemy: Matching (0)/Enemy": 14041813, - "Aztec Llama Temple Enemy: Matching (1)/Enemy": 14041814, - "Aztec Llama Temple Enemy: Right/Enemy": 14041815, - "Aztec Llama Temple Enemy: Left/Enemy": 14041816, - "Aztec Llama Temple Enemy: Melon Crate/Enemy": 14041817, - "Aztec Llama Temple Enemy: Slam Switch/Enemy": 14041818, - "Aztec Tiny Temple Enemy: Guard Rotating (0)/Enemy": 14041819, - "Aztec Tiny Temple Enemy: Guard Rotating (1)/Enemy": 14041820, - "Aztec Tiny Temple Enemy: Main Room (0)/Enemy": 14041821, - "Aztec Tiny Temple Enemy: Main Room (1)/Enemy": 14041822, - "Aztec Tiny Temple Enemy: Main Room (2)/Enemy": 14041823, - "Aztec Tiny Temple Enemy: Kong Room (0)/Enemy": 14041824, - "Aztec Tiny Temple Enemy: Kong Room (1)/Enemy": 14041825, - "Aztec Tiny Temple Enemy: Kong Room (2)/Enemy": 14041826, - "Aztec Tiny Temple Enemy: Kong Room (3)/Enemy": 14041827, - "Aztec Tiny Temple Enemy: Kong Room (4)/Enemy": 14041828, - "Frantic Factory Enemy: Candy Cranky (0)/Enemy": 14041829, - "Frantic Factory Enemy: Candy Cranky (1)/Enemy": 14041830, - "Frantic Factory Enemy: Lobby Left/Enemy": 14041831, - "Frantic Factory Enemy: Lobby Right/Enemy": 14041832, - "Frantic Factory Enemy: Storage Room/Enemy": 14041833, - "Frantic Factory Enemy: Block Tower (0)/Enemy": 14041834, - "Frantic Factory Enemy: Block Tower (1)/Enemy": 14041835, - "Frantic Factory Enemy: Block Tower (2)/Enemy": 14041836, - "Frantic Factory Enemy: Tunnel To Hatch/Enemy": 14041837, - "Frantic Factory Enemy: Tunnel To Prod (0)/Enemy": 14041838, - "Frantic Factory Enemy: Tunnel To Prod (1)/Enemy": 14041839, - "Frantic Factory Enemy: Tunnel To Block Tower/Enemy": 14041840, - "Frantic Factory Enemy: Tunnel To Race (0)/Enemy": 14041841, - "Frantic Factory Enemy: Tunnel To Race (1)/Enemy": 14041842, - "Frantic Factory Enemy: Low Warp 4/Enemy": 14041843, - "Frantic Factory Enemy: Diddy Switch/Enemy": 14041844, - "Frantic Factory Enemy: To Block Tower Tunnel/Enemy": 14041845, - "Frantic Factory Enemy: Dark Room (0)/Enemy": 14041846, - "Frantic Factory Enemy: Dark Room (1)/Enemy": 14041847, - "Frantic Factory Lobby Enemy: Enemy (0)/Enemy": 14041848, - "Gloomy Galleon Enemy: Chest Room (0)/Enemy": 14041849, - "Gloomy Galleon Enemy: Chest Room (1)/Enemy": 14041850, - "Gloomy Galleon Enemy: Near Vine Cannon/Enemy": 14041851, - "Gloomy Galleon Enemy: Cranky Cannon/Enemy": 14041852, - "Gloomy Galleon Enemy: Peanut Tunnel/Enemy": 14041853, - "Gloomy Galleon Enemy: Coconut Tunnel/Enemy": 14041854, + "Forest Lanky Attic Shooting/Forest Lanky Attic Shooting": 14041347, + "Forest Kasplat: Behind DK's Barn/Forest Kasplat: Behind DK's Barn": 14041348, + "Forest Donkey Thornvine Barn Barrel/Forest Donkey Thornvine Barn Barrel": 14041349, + "Forest Fairy (Thornvine Barn)/Forest Fairy (Thornvine Barn)": 14041350, + "Forest Tiny Top of Beanstalk/Forest Tiny Top of the Beanstalk": 14041351, + "Forest Chunky Apple Rescue/Forest Chunky Apple Rescue": 14041352, + "Forest Anthill/Forest Second Anthill Reward": 14041353, + "Medals/Forest Boss Defeated": 14041354, + "Medals/Caves Donkey Medal": 14041355, + "Medals/Caves Diddy Medal": 14041356, + "Medals/Caves Lanky Medal": 14041357, + "Medals/Caves Tiny Medal": 14041358, + "Medals/Caves Chunky Medal": 14041359, + "Caves DK Baboon Blast/Caves Donkey Baboon Blast": 14041360, + "Caves Diddy Jetpack Barrel/Caves Diddy Jetpack Barrel": 14041361, + "Caves Tiny Mini Cave Barrel/Caves Tiny Mini Cave Barrel": 14041362, + "Caves Tiny Monkeyport Igloo/Caves Tiny Monkeyport Igloo": 14041363, + "Caves Chunky Gorilla Gone/Caves Chunky Gorilla Gone": 14041364, + "Caves Kasplat: Near Ice Castle/Caves Kasplat: Near Ice Castle": 14041365, + "Caves Kasplat: Mini Room by Funky/Caves Kasplat: Mini Room by Funky": 14041366, + "Caves Kasplat: On the Pillar/Caves Kasplat: On the Pillar": 14041367, + "Caves Kasplat: By the Far Warp 2/Caves Kasplat: By the Far Warp 2": 14041368, + "Caves Lanky Beetle Race/Caves Lanky Beetle Race": 14041369, + "Caves Lanky Ice Castle Slam Challenge/Caves Lanky Ice Castle Slam Challenge": 14041370, + "Caves Chunky Transparent Igloo/Caves Chunky Transparent Igloo": 14041371, + "Caves Kasplat: On 5-Door Igloo/Caves Kasplat: On 5-Door Igloo": 14041372, + "Caves DK 5 Door Igloo/Caves Donkey 5 Door Igloo": 14041373, + "Caves Diddy 5 Door Igloo/Caves Diddy 5 Door Igloo": 14041374, + "Caves Lanky 5 Door Igloo/Caves Lanky 5 Door Igloo": 14041375, + "Caves Tiny 5 Door Igloo/Caves Tiny 5 Door Igloo": 14041376, + "Caves Tiny 5 Door Igloo/Caves Fairy (Tiny Igloo)": 14041377, + "Caves Chunky 5 Door Igloo/Caves Chunky 5 Door Igloo": 14041378, + "Rotating Cabin/Caves Donkey Rotating Cabin": 14041379, + "Rotating Cabin/Caves Battle Arena (Rotating Room: Left Portion)": 14041380, + "Caves DK 5 Door Cabin/Caves Donkey 5 Door Cabin": 14041381, + "Caves Diddy 5 Door Cabin Lower/Caves Diddy 5 Door Cabin Lower": 14041382, + "Caves Diddy 5 Door Cabin Upper/Caves Diddy 5 Door Cabin Upper": 14041383, + "Caves Diddy 5 Door Cabin Upper/Caves Fairy (Diddy Candles Cabin)": 14041384, + "Caves Lanky Sprint Cabin/Caves Lanky Sprint Cabin": 14041385, + "Caves Tiny 5 Door Cabin/Caves Tiny 5 Door Cabin": 14041386, + "Caves Chunky 5 Door Cabin/Caves Chunky 5 Door Cabin": 14041387, + "Medals/Caves Boss Defeated": 14041388, + "Medals/Castle Donkey Medal": 14041389, + "Medals/Castle Diddy Medal": 14041390, + "Medals/Castle Lanky Medal": 14041391, + "Medals/Castle Tiny Medal": 14041392, + "Medals/Castle Chunky Medal": 14041393, + "Castle Diddy Above Castle/Castle Diddy Above Castle": 14041394, + "Castle Kasplat: Near Upper Warp 2/Castle Kasplat: Near Upper Warp 2": 14041395, + "Castle Kasplat: On a Lone Platform/Castle Kasplat: On a lone platform": 14041396, + "Inside the Tree/Castle Donkey Tree Sniping": 14041397, + "Inside the Tree/Castle Chunky Tree Sniping Barrel": 14041398, + "Inside the Tree/Castle Kasplat: Inside the Tree": 14041399, + "Inside the Tree/Castle Fairy (Tree Sniper Room)": 14041400, + "Castle DK Library/Castle Donkey Library": 14041401, + "Castle Diddy Ballroom/Castle Diddy Ballroom": 14041402, + "Castle Fairy (Near Car Race)/Castle Fairy (Near Car Race)": 14041403, + "Castle Tiny Car Race/Castle Tiny Car Race": 14041404, + "Castle Lanky Tower/Castle Lanky Tower": 14041405, + "Greenhouse/Castle Lanky Greenhouse": 14041406, + "Greenhouse/Castle Battle Arena (Greenhouse: Center)": 14041407, + "Castle Tiny Trashcan/Castle Tiny Trash Can": 14041408, + "Castle Chunky Shed/Castle Chunky Shed": 14041409, + "Castle Chunky Museum/Castle Chunky Museum": 14041410, + "Castle Kasplat: Lower Cave Center/Castle Kasplat: Lower Cave Center": 14041411, + "Castle Diddy Crypt/Castle Diddy Crypt": 14041412, + "Castle Chunky Crypt/Castle Chunky Crypt": 14041413, + "Castle DK Minecart/Castle Donkey Minecart": 14041414, + "Mausoleum/Castle Lanky Mausoleum": 14041415, + "Mausoleum/Castle Tiny Mausoleum": 14041416, + "Castle Tiny Over Chasm/Castle Tiny Over Chasm": 14041417, + "Castle Kasplat: Near Candy's/Castle Kasplat: Near Candy's": 14041418, + "Castle DK Dungeon/Castle Donkey Dungeon": 14041419, + "Castle Diddy Dungeon/Castle Diddy Dungeon": 14041420, + "Castle Lanky Dungeon/Castle Lanky Dungeon": 14041421, + "Medals/Castle Boss Defeated": 14041422, + "Helm Battle Arena/Helm Battle Arena (Top of Blast-o-Matic)": 14041433, + "Helm DK Medal/Helm Donkey Medal": 14041434, + "Helm Chunky Medal/Helm Chunky Medal": 14041435, + "Helm Tiny Medal/Helm Tiny Medal": 14041436, + "Helm Lanky Medal/Helm Lanky Medal": 14041437, + "Helm Diddy Medal/Helm Diddy Medal": 14041438, + "Helm Fairy (Key 8 Room)/Helm Fairy (Key 8 Room (1))": 14041439, + "Helm Fairy (Key 8 Room)/Helm Fairy (Key 8 Room (2))": 14041440, + "The End of Helm/The End of Helm": 14041441, + "Isles Cranky/Isles Cranky Shared": 14041442, + "Japes Cranky/Japes Cranky Donkey": 14041443, + "Japes Cranky/Japes Cranky Diddy": 14041444, + "Japes Cranky/Japes Cranky Lanky": 14041445, + "Japes Cranky/Japes Cranky Tiny": 14041446, + "Japes Cranky/Japes Cranky Chunky": 14041447, + "Japes Funky/Japes Funky Donkey": 14041448, + "Japes Funky/Japes Funky Diddy": 14041449, + "Japes Funky/Japes Funky Lanky": 14041450, + "Japes Funky/Japes Funky Tiny": 14041451, + "Japes Funky/Japes Funky Chunky": 14041452, + "Aztec Cranky/Aztec Cranky Donkey": 14041453, + "Aztec Cranky/Aztec Cranky Diddy": 14041454, + "Aztec Candy/Aztec Candy Donkey": 14041455, + "Aztec Candy/Aztec Candy Diddy": 14041456, + "Aztec Candy/Aztec Candy Lanky": 14041457, + "Aztec Candy/Aztec Candy Tiny": 14041458, + "Aztec Candy/Aztec Candy Chunky": 14041459, + "Factory Cranky/Factory Cranky Donkey": 14041460, + "Factory Cranky/Factory Cranky Diddy": 14041461, + "Factory Cranky/Factory Cranky Lanky": 14041462, + "Factory Cranky/Factory Cranky Tiny": 14041463, + "Factory Cranky/Factory Cranky Chunky": 14041464, + "Factory Funky/Factory Funky Shared": 14041465, + "Galleon Candy/Galleon Candy Shared": 14041466, + "Forest Cranky/Forest Cranky Shared": 14041467, + "Forest Funky/Forest Funky Shared": 14041468, + "Caves Cranky/Caves Cranky Lanky": 14041469, + "Caves Cranky/Caves Cranky Tiny": 14041470, + "Caves Cranky/Caves Cranky Chunky": 14041471, + "Caves Funky/Caves Funky Shared": 14041472, + "Caves Candy/Caves Candy Shared": 14041473, + "Castle Cranky/Castle Cranky Shared": 14041474, + "Castle Funky/Castle Funky Shared": 14041475, + "Castle Candy/Castle Candy Shared": 14041476, + "Isles Cranky/Jetpac": 14041477, + "Japes Cranky/Japes Cranky Shared": 14041478, + "Japes Funky/Japes Funky Shared": 14041479, + "Aztec Cranky/Aztec Cranky Shared": 14041480, + "Aztec Cranky/Aztec Cranky Lanky": 14041481, + "Aztec Cranky/Aztec Cranky Tiny": 14041482, + "Aztec Cranky/Aztec Cranky Chunky": 14041483, + "Aztec Funky/Aztec Funky Shared": 14041484, + "Aztec Funky/Aztec Funky Donkey": 14041485, + "Aztec Funky/Aztec Funky Diddy": 14041486, + "Aztec Funky/Aztec Funky Lanky": 14041487, + "Aztec Funky/Aztec Funky Tiny": 14041488, + "Aztec Funky/Aztec Funky Chunky": 14041489, + "Aztec Candy/Aztec Candy Shared": 14041490, + "Factory Cranky/Factory Cranky Shared": 14041491, + "Factory Funky/Factory Funky Donkey": 14041492, + "Factory Funky/Factory Funky Diddy": 14041493, + "Factory Funky/Factory Funky Lanky": 14041494, + "Factory Funky/Factory Funky Tiny": 14041495, + "Factory Funky/Factory Funky Chunky": 14041496, + "Factory Candy/Factory Candy Shared": 14041497, + "Factory Candy/Factory Candy Donkey": 14041498, + "Factory Candy/Factory Candy Diddy": 14041499, + "Factory Candy/Factory Candy Lanky": 14041500, + "Factory Candy/Factory Candy Tiny": 14041501, + "Factory Candy/Factory Candy Chunky": 14041502, + "Galleon Cranky/Galleon Cranky Shared": 14041503, + "Galleon Cranky/Galleon Cranky Donkey": 14041504, + "Galleon Cranky/Galleon Cranky Diddy": 14041505, + "Galleon Cranky/Galleon Cranky Lanky": 14041506, + "Galleon Cranky/Galleon Cranky Tiny": 14041507, + "Galleon Cranky/Galleon Cranky Chunky": 14041508, + "Galleon Funky/Galleon Funky Shared": 14041509, + "Galleon Funky/Galleon Funky Donkey": 14041510, + "Galleon Funky/Galleon Funky Diddy": 14041511, + "Galleon Funky/Galleon Funky Lanky": 14041512, + "Galleon Funky/Galleon Funky Tiny": 14041513, + "Galleon Funky/Galleon Funky Chunky": 14041514, + "Galleon Candy/Galleon Candy Donkey": 14041515, + "Galleon Candy/Galleon Candy Diddy": 14041516, + "Galleon Candy/Galleon Candy Lanky": 14041517, + "Galleon Candy/Galleon Candy Tiny": 14041518, + "Galleon Candy/Galleon Candy Chunky": 14041519, + "Forest Cranky/Forest Cranky Donkey": 14041520, + "Forest Cranky/Forest Cranky Diddy": 14041521, + "Forest Cranky/Forest Cranky Lanky": 14041522, + "Forest Cranky/Forest Cranky Tiny": 14041523, + "Forest Cranky/Forest Cranky Chunky": 14041524, + "Forest Funky/Forest Funky Donkey": 14041525, + "Forest Funky/Forest Funky Diddy": 14041526, + "Forest Funky/Forest Funky Lanky": 14041527, + "Forest Funky/Forest Funky Tiny": 14041528, + "Forest Funky/Forest Funky Chunky": 14041529, + "Caves Cranky/Caves Cranky Shared": 14041530, + "Caves Cranky/Caves Cranky Donkey": 14041531, + "Caves Cranky/Caves Cranky Diddy": 14041532, + "Caves Funky/Caves Funky Donkey": 14041533, + "Caves Funky/Caves Funky Diddy": 14041534, + "Caves Funky/Caves Funky Lanky": 14041535, + "Caves Funky/Caves Funky Tiny": 14041536, + "Caves Funky/Caves Funky Chunky": 14041537, + "Caves Candy/Caves Candy Donkey": 14041538, + "Caves Candy/Caves Candy Diddy": 14041539, + "Caves Candy/Caves Candy Lanky": 14041540, + "Caves Candy/Caves Candy Tiny": 14041541, + "Caves Candy/Caves Candy Chunky": 14041542, + "Castle Cranky/Castle Cranky Donkey": 14041543, + "Castle Cranky/Castle Cranky Diddy": 14041544, + "Castle Cranky/Castle Cranky Lanky": 14041545, + "Castle Cranky/Castle Cranky Tiny": 14041546, + "Castle Cranky/Castle Cranky Chunky": 14041547, + "Castle Funky/Castle Funky Donkey": 14041548, + "Castle Funky/Castle Funky Diddy": 14041549, + "Castle Funky/Castle Funky Lanky": 14041550, + "Castle Funky/Castle Funky Tiny": 14041551, + "Castle Funky/Castle Funky Chunky": 14041552, + "Castle Candy/Castle Candy Donkey": 14041553, + "Castle Candy/Castle Candy Diddy": 14041554, + "Castle Candy/Castle Candy Lanky": 14041555, + "Castle Candy/Castle Candy Tiny": 14041556, + "Castle Candy/Castle Candy Chunky": 14041557, + "Isles Cranky/Isles Cranky Donkey": 14041558, + "Isles Cranky/Isles Cranky Diddy": 14041559, + "Isles Cranky/Isles Cranky Lanky": 14041560, + "Isles Cranky/Isles Cranky Tiny": 14041561, + "Isles Cranky/Isles Cranky Chunky": 14041562, + "Turn in 1 Blueprint/Turning In 1 Blueprint": 14041563, + "Turn in 2 Blueprints/Turning In 2 Blueprints": 14041564, + "Turn in 3 Blueprints/Turning In 3 Blueprints": 14041565, + "Turn in 4 Blueprints/Turning In 4 Blueprints": 14041566, + "Turn in 5 Blueprints/Turning In 5 Blueprints": 14041567, + "Turn in 6 Blueprints/Turning In 6 Blueprints": 14041568, + "Turn in 7 Blueprints/Turning In 7 Blueprints": 14041569, + "Turn in 8 Blueprints/Turning In 8 Blueprints": 14041570, + "Turn in 9 Blueprints/Turning In 9 Blueprints": 14041571, + "Turn in 10 Blueprints/Turning In 10 Blueprints": 14041572, + "Turn in 11 Blueprints/Turning In 11 Blueprints": 14041573, + "Turn in 12 Blueprints/Turning In 12 Blueprints": 14041574, + "Turn in 13 Blueprints/Turning In 13 Blueprints": 14041575, + "Turn in 14 Blueprints/Turning In 14 Blueprints": 14041576, + "Turn in 15 Blueprints/Turning In 15 Blueprints": 14041577, + "Turn in 16 Blueprints/Turning In 16 Blueprints": 14041578, + "Turn in 17 Blueprints/Turning In 17 Blueprints": 14041579, + "Turn in 18 Blueprints/Turning In 18 Blueprints": 14041580, + "Turn in 19 Blueprints/Turning In 19 Blueprints": 14041581, + "Turn in 20 Blueprints/Turning In 20 Blueprints": 14041582, + "Turn in 21 Blueprints/Turning In 21 Blueprints": 14041583, + "Turn in 22 Blueprints/Turning In 22 Blueprints": 14041584, + "Turn in 23 Blueprints/Turning In 23 Blueprints": 14041585, + "Turn in 24 Blueprints/Turning In 24 Blueprints": 14041586, + "Turn in 25 Blueprints/Turning In 25 Blueprints": 14041587, + "Turn in 26 Blueprints/Turning In 26 Blueprints": 14041588, + "Turn in 27 Blueprints/Turning In 27 Blueprints": 14041589, + "Turn in 28 Blueprints/Turning In 28 Blueprints": 14041590, + "Turn in 29 Blueprints/Turning In 29 Blueprints": 14041591, + "Turn in 30 Blueprints/Turning In 30 Blueprints": 14041592, + "Turn in 31 Blueprints/Turning In 31 Blueprints": 14041593, + "Turn in 32 Blueprints/Turning In 32 Blueprints": 14041594, + "Turn in 33 Blueprints/Turning In 33 Blueprints": 14041595, + "Turn in 34 Blueprints/Turning In 34 Blueprints": 14041596, + "Turn in 35 Blueprints/Turning In 35 Blueprints": 14041597, + "Turn in 36 Blueprints/Turning In 36 Blueprints": 14041598, + "Turn in 37 Blueprints/Turning In 37 Blueprints": 14041599, + "Turn in 38 Blueprints/Turning In 38 Blueprints": 14041600, + "Turn in 39 Blueprints/Turning In 39 Blueprints": 14041601, + "Turn in 40 Blueprints/Turning In 40 Blueprints": 14041602, + "Japes DK Wrinkly Door/Japes Donkey Hint Door": 14041603, + "Japes Diddy Wrinkly Door/Japes Diddy Hint Door": 14041604, + "Japes Lanky Wrinkly Door/Japes Lanky Hint Door": 14041605, + "Japes Tiny Wrinkly Door/Japes Tiny Hint Door": 14041606, + "Japes Chunky Wrinkly Door/Japes Chunky Hint Door": 14041607, + "Aztec DK Wrinkly Door/Aztec Donkey Hint Door": 14041608, + "Aztec Diddy Wrinkly Door/Aztec Diddy Hint Door": 14041609, + "Aztec Lanky Wrinkly Door/Aztec Lanky Hint Door": 14041610, + "Aztec Tiny Wrinkly Door/Aztec Tiny Hint Door": 14041611, + "Aztec Chunky Wrinkly Door/Aztec Chunky Hint Door": 14041612, + "Factory DK Wrinkly Door/Factory Donkey Hint Door": 14041613, + "Factory Diddy Wrinkly Door/Factory Diddy Hint Door": 14041614, + "Factory Lanky Wrinkly Door/Factory Lanky Hint Door": 14041615, + "Factory Tiny Wrinkly Door/Factory Tiny Hint Door": 14041616, + "Factory Chunky Wrinkly Door/Factory Chunky Hint Door": 14041617, + "Galleon DK Hint Door/Galleon Donkey Hint Door": 14041618, + "Galleon Diddy Hint Door/Galleon Diddy Hint Door": 14041619, + "Galleon Lanky Hint Door/Galleon Lanky Hint Door": 14041620, + "Galleon Tiny Hint Door/Galleon Tiny Hint Door": 14041621, + "Galleon Chunky Hint Door/Galleon Chunky Hint Door": 14041622, + "Forest DK Hint Door/Forest Donkey Hint Door": 14041623, + "Forest Diddy Hint Door/Forest Diddy Hint Door": 14041624, + "Forest Lanky Hint Door/Forest Lanky Hint Door": 14041625, + "Forest Tiny Hint Door/Forest Tiny Hint Door": 14041626, + "Forest Chunky Hint Door/Forest Chunky Hint Door": 14041627, + "Caves DK Hint Door/Caves Donkey Hint Door": 14041628, + "Caves Diddy Hint Door/Caves Diddy Hint Door": 14041629, + "Caves Lanky Hint Door/Caves Lanky Hint Door": 14041630, + "Caves Tiny Hint Door/Caves Tiny Hint Door": 14041631, + "Caves Chunky Hint Door/Caves Chunky Hint Door": 14041632, + "Castle DK Hint Door/Castle Donkey Hint Door": 14041633, + "Castle Diddy Hint Door/Castle Diddy Hint Door": 14041634, + "Castle Lanky Hint Door/Castle Lanky Hint Door": 14041635, + "Castle Tiny Hint Door/Castle Tiny Hint Door": 14041636, + "Castle Chunky Hint Door/Castle Chunky Hint Door": 14041637, + "Japes Dirt: Painting Hill/Japes Dirt: Painting Hill": 14041673, + "5 Door Temple/Aztec Dirt: Chunky Temple": 14041674, + "Factory Dirt: Dark Room/Factory Dirt: Dark Room": 14041675, + "Isles Dirt: Cabin Isle/Isles Dirt: Cabin Isle": 14041676, + "Isles Dirt: Under Caves Lobby/Isles Dirt: Under Caves Lobby": 14041677, + "Isles Dirt: Aztec Roof/Isles Dirt: Aztec Roof": 14041678, + "Aztec Dirt: Oasis/Aztec Dirt: Oasis": 14041679, + "Forest Dirt: Near Mills Grass/Forest Dirt: Mills Grass": 14041680, + "Forest Dirt: Beanstalk/Forest Dirt: Beanstalk": 14041681, + "Lighthouse/Galleon Dirt: Lighthouse": 14041682, + "Caves Dirt: Giant Kosha/Caves Dirt: Giant Kosha": 14041683, + "Castle Dirt: Top Floor/Castle Dirt: Top Floor": 14041684, + "K. Lumsy Prison/Isles Dirt: Back of Prison": 14041685, + "Isles Dirt: Training Grounds Rear Tunnel/Isles Dirt: Training Grounds Rear Tunnel": 14041686, + "Isles Dirt: Banana Hoard/Isles Dirt: Banana Hoard": 14041687, + "Upper Castle Lobby/Isles Dirt: Castle Lobby": 14041688, + "Japes Crate: Behind the Mountain/Japes Crate: Behind the Mountain": 14041689, + "Japes Crate: In the Rambi Cave/Japes Crate: In the Rambi Cave": 14041690, + "Aztec Crate: Llama Temple/Aztec Crate: Llama Temple Entrance": 14041691, + "Factory Crate: Near Funky/Factory Crate: Near Funky": 14041692, + "Factory Crate: Near Candy/Factory Crate: Near Candy": 14041693, + "Galleon Crate: Near Cactus/Galleon Crate: Near Cactus": 14041694, + "Aztec Crate: On Llama Temple/Aztec Crate: On Llama Temple": 14041695, + "Aztec Crate: Near Gong Tower/Aztec Crate: Near Gong Tower": 14041696, + "Forest Crate: Near Owl Tree/Forest Crate: Near Owl Tree": 14041697, + "Forest Crate: Near Thornvine Barn/Forest Crate: Near Thornvine Barn": 14041698, + "Forest Crate: Behind Dark Attic/Forest Crate: Behind Dark Attic": 14041699, + "Forest Crate: In Thornvine Barn/Forest Crate: In Thornvine Barn": 14041700, + "Castle Crate: Behind Mausoleum Entrance/Castle Crate: Behind Mausoleum Entrance": 14041701, + "Isles Boulder: Near Level 2/Isles Boulder: Near Level 2": 14041702, + "Isles Chunky Triangle Pad/Isles Boulder: Near Level 6": 14041703, + "Aztec Boulder: Tunnel/Aztec Boulder: Tunnel": 14041704, + "Caves Boulder: Small/Caves Boulder: Small": 14041705, + "Caves Boulder: Large/Caves Boulder: Large": 14041706, + "Castle Boulder: Museum/Castle Boulder: Museum": 14041707, + "Isles Lanky Instrument Pad/Isles Boulder: Japes Lobby": 14041708, + "Isles Boulder: Castle Lobby/Isles Boulder: Castle Lobby": 14041709, + "Isles Boulder: Caves Lobby/Isles Boulder: Caves Lobby": 14041710, + "Forest Keg: Mill Front Near/Forest Keg: Mill Front Near": 14041711, + "Forest Keg: Mill Front Far/Forest Keg: Mill Front Far": 14041712, + "Forest Keg: Mill Back/Forest Keg: Mill Back": 14041713, + "Aztec Chunky Vases/Aztec Vase: Circle": 14041714, + "Aztec Chunky Vases/Aztec Vase: Colon": 14041715, + "Aztec Chunky Vases/Aztec Vase: Triangle": 14041716, + "Aztec Chunky Vases/Aztec Vase: Plus": 14041717, + "Jungle Japes Enemy: Start/Japes Enemy: Start": 14041718, + "Jungle Japes Enemy: Diddy Cavern/Japes Enemy: Diddy Cavern": 14041719, + "Jungle Japes Enemy: Tunnel (0)/Japes Enemy: Tunnel (0)": 14041720, + "Jungle Japes Enemy: Tunnel (1)/Japes Enemy: Tunnel (1)": 14041721, + "Jungle Japes Enemy: Storm (0)/Japes Enemy: Storm (0)": 14041722, + "Jungle Japes Enemy: Storm (1)/Japes Enemy: Storm (1)": 14041723, + "Jungle Japes Enemy: Storm (2)/Japes Enemy: Storm (2)": 14041724, + "Jungle Japes Enemy: Hive (0)/Japes Enemy: Hive (0)": 14041725, + "Jungle Japes Enemy: Hive (1)/Japes Enemy: Hive (1)": 14041726, + "Jungle Japes Enemy: Hive (2)/Japes Enemy: Hive (2)": 14041727, + "Jungle Japes Enemy: Hive (3)/Japes Enemy: Hive (3)": 14041728, + "Jungle Japes Enemy: Hive (4)/Japes Enemy: Hive (4)": 14041729, + "Jungle Japes Enemy: Killed In Demo/Japes Enemy: Killed In Demo": 14041730, + "Jungle Japes Enemy: Near Underground/Japes Enemy: Near Underground": 14041731, + "Jungle Japes Enemy: Near Painting (0)/Japes Enemy: Near Painting (0)": 14041732, + "Jungle Japes Enemy: Near Painting (1)/Japes Enemy: Near Painting (1)": 14041733, + "Jungle Japes Enemy: Near Painting (2)/Japes Enemy: Near Painting (2)": 14041734, + "Jungle Japes Enemy: Mountain/Japes Enemy: Mountain": 14041735, + "Jungle Japes Enemy: Feather Tunnel/Japes Enemy: Feather Tunnel": 14041736, + "Jungle Japes Enemy: Middle Tunnel/Japes Enemy: Middle Tunnel": 14041737, + "Jungle Japes Lobby Enemy: Enemy (0)/Isles Japes Lobby Enemy: Enemy (0)": 14041738, + "Jungle Japes Lobby Enemy: Enemy (1)/Isles Japes Lobby Enemy: Enemy (1)": 14041739, + "Japes Mountain Enemy: Start (0)/Japes Mountain Enemy: Start (0)": 14041740, + "Japes Mountain Enemy: Start (1)/Japes Mountain Enemy: Start (1)": 14041741, + "Japes Mountain Enemy: Start (2)/Japes Mountain Enemy: Start (2)": 14041742, + "Japes Mountain Enemy: Start (3)/Japes Mountain Enemy: Start (3)": 14041743, + "Japes Mountain Enemy: Start (4)/Japes Mountain Enemy: Start (4)": 14041744, + "Japes Mountain Enemy: Near Gate Switch (0)/Japes Mountain Enemy: Near Gate Switch (0)": 14041745, + "Japes Mountain Enemy: Near Gate Switch (1)/Japes Mountain Enemy: Near Gate Switch (1)": 14041746, + "Japes Mountain Enemy: Hi Lo/Japes Mountain Enemy: Hi Lo": 14041747, + "Japes Mountain Enemy: Conveyor (0)/Japes Mountain Enemy: Conveyor (0)": 14041748, + "Japes Mountain Enemy: Conveyor (1)/Japes Mountain Enemy: Conveyor (1)": 14041749, + "Japes Tiny Hive Enemy: First Room/Japes Tiny Hive Enemy: First Room": 14041750, + "Japes Tiny Hive Enemy: Second Room (0)/Japes Tiny Hive Enemy: Second Room (0)": 14041751, + "Japes Tiny Hive Enemy: Second Room (1)/Japes Tiny Hive Enemy: Second Room (1)": 14041752, + "Japes Tiny Hive Enemy: Third Room (0)/Japes Tiny Hive Enemy: Third Room (0)": 14041753, + "Japes Tiny Hive Enemy: Third Room (1)/Japes Tiny Hive Enemy: Third Room (1)": 14041754, + "Japes Tiny Hive Enemy: Third Room (2)/Japes Tiny Hive Enemy: Third Room (2)": 14041755, + "Japes Tiny Hive Enemy: Third Room (3)/Japes Tiny Hive Enemy: Third Room (3)": 14041756, + "Japes Tiny Hive Enemy: Main Room/Japes Tiny Hive Enemy: Main Room": 14041757, + "Angry Aztec Enemy: Vase Room (0)/Aztec Enemy: Vase Room (0)": 14041758, + "Angry Aztec Enemy: Vase Room (1)/Aztec Enemy: Vase Room (1)": 14041759, + "Angry Aztec Enemy: Vase Room (2)/Aztec Enemy: Vase Room (2)": 14041760, + "Angry Aztec Enemy: Tunnel Pad (0)/Aztec Enemy: Tunnel Pad (0)": 14041761, + "Angry Aztec Enemy: Tunnel Cage (0)/Aztec Enemy: Tunnel Cage (0)": 14041762, + "Angry Aztec Enemy: Tunnel Cage (1)/Aztec Enemy: Tunnel Cage (1)": 14041763, + "Angry Aztec Enemy: Tunnel Cage (2)/Aztec Enemy: Tunnel Cage (2)": 14041764, + "Angry Aztec Enemy: Starting Tunnel (0)/Aztec Enemy: Starting Tunnel (0)": 14041765, + "Angry Aztec Enemy: Starting Tunnel (1)/Aztec Enemy: Starting Tunnel (1)": 14041766, + "Angry Aztec Enemy: Oasis Door/Aztec Enemy: Oasis Door": 14041767, + "Angry Aztec Enemy: Tunnel Cage (3)/Aztec Enemy: Tunnel Cage (3)": 14041768, + "Angry Aztec Enemy: Outside Llama/Aztec Enemy: Outside Llama": 14041769, + "Angry Aztec Enemy: Outside Tower/Aztec Enemy: Outside Tower": 14041770, + "Angry Aztec Enemy: Tunnel Pad (1)/Aztec Enemy: Tunnel Pad (1)": 14041771, + "Angry Aztec Enemy: Near Candy/Aztec Enemy: Near Candy": 14041772, + "Angry Aztec Enemy: Around Totem/Aztec Enemy: Around Totem": 14041773, + "Angry Aztec Enemy: Starting Tunnel (2)/Aztec Enemy: Starting Tunnel (2)": 14041774, + "Angry Aztec Enemy: Starting Tunnel (3)/Aztec Enemy: Starting Tunnel (3)": 14041775, + "Angry Aztec Enemy: Outside Snide/Aztec Enemy: Outside Snide": 14041776, + "Angry Aztec Enemy: Outside 5DT/Aztec Enemy: Outside 5DT": 14041777, + "Angry Aztec Enemy: Near Sealed Quicksand Tunnel/Aztec Enemy: Near Sealed Quicksand Tunnel": 14041778, + "Aztec Donkey 5DTemple Enemy: Start Trap (0)/Aztec Donkey 5DTemple Enemy: Start Trap (0)": 14041779, + "Aztec Donkey 5DTemple Enemy: Start Trap (1)/Aztec Donkey 5DTemple Enemy: Start Trap (1)": 14041780, + "Aztec Donkey 5DTemple Enemy: Start Trap (2)/Aztec Donkey 5DTemple Enemy: Start Trap (2)": 14041781, + "Aztec Donkey 5DTemple Enemy: End Trap (0)/Aztec Donkey 5DTemple Enemy: End Trap (0)": 14041782, + "Aztec Donkey 5DTemple Enemy: End Trap (1)/Aztec Donkey 5DTemple Enemy: End Trap (1)": 14041783, + "Aztec Donkey 5DTemple Enemy: End Trap (2)/Aztec Donkey 5DTemple Enemy: End Trap (2)": 14041784, + "Aztec Donkey 5DTemple Enemy: End Path (0)/Aztec Donkey 5DTemple Enemy: End Path (0)": 14041785, + "Aztec Donkey 5DTemple Enemy: End Path (1)/Aztec Donkey 5DTemple Enemy: End Path (1)": 14041786, + "Aztec Donkey 5DTemple Enemy: Start Path/Aztec Donkey 5DTemple Enemy: Start Path": 14041787, + "Aztec Diddy 5DTemple Enemy: End Trap (0)/Aztec Diddy 5DTemple Enemy: End Trap (0)": 14041788, + "Aztec Diddy 5DTemple Enemy: End Trap (1)/Aztec Diddy 5DTemple Enemy: End Trap (1)": 14041789, + "Aztec Diddy 5DTemple Enemy: End Trap (2)/Aztec Diddy 5DTemple Enemy: End Trap (2)": 14041790, + "Aztec Diddy 5DTemple Enemy: Start Left (0)/Aztec Diddy 5DTemple Enemy: Start Left (0)": 14041791, + "Aztec Diddy 5DTemple Enemy: Start Left (1)/Aztec Diddy 5DTemple Enemy: Start Left (1)": 14041792, + "Aztec Diddy 5DTemple Enemy: Reward/Aztec Diddy 5DTemple Enemy: Reward": 14041793, + "Aztec Diddy 5DTemple Enemy: Second Switch/Aztec Diddy 5DTemple Enemy: Second Switch": 14041794, + "Aztec Lanky 5DTemple Enemy: Joining Paths/Aztec Lanky 5DTemple Enemy: Joining Paths": 14041795, + "Aztec Lanky 5DTemple Enemy: End Trap/Aztec Lanky 5DTemple Enemy: End Trap": 14041796, + "Aztec Lanky 5DTemple Enemy: Reward/Aztec Lanky 5DTemple Enemy: Reward": 14041797, + "Aztec Tiny 5DTemple Enemy: Start Right Front/Aztec Tiny 5DTemple Enemy: Start Right Front": 14041798, + "Aztec Tiny 5DTemple Enemy: Start Left Back/Aztec Tiny 5DTemple Enemy: Start Left Back": 14041799, + "Aztec Tiny 5DTemple Enemy: Start Right Back/Aztec Tiny 5DTemple Enemy: Start Right Back": 14041800, + "Aztec Tiny 5DTemple Enemy: Start Left Front/Aztec Tiny 5DTemple Enemy: Start Left Front": 14041801, + "Aztec Tiny 5DTemple Enemy: Reward (0)/Aztec Tiny 5DTemple Enemy: Reward (0)": 14041802, + "Aztec Tiny 5DTemple Enemy: Reward (1)/Aztec Tiny 5DTemple Enemy: Reward (1)": 14041803, + "Aztec Tiny 5DTemple Enemy: Dead End (0)/Aztec Tiny 5DTemple Enemy: Dead End (0)": 14041804, + "Aztec Tiny 5DTemple Enemy: Dead End (1)/Aztec Tiny 5DTemple Enemy: Dead End (1)": 14041805, + "Aztec Chunky 5DTemple Enemy: Start Right/Aztec Chunky 5DTemple Enemy: Start Right": 14041806, + "Aztec Chunky 5DTemple Enemy: Start Left/Aztec Chunky 5DTemple Enemy: Start Left": 14041807, + "Aztec Chunky 5DTemple Enemy: Second Right/Aztec Chunky 5DTemple Enemy: Second Right": 14041808, + "Aztec Chunky 5DTemple Enemy: Second Left/Aztec Chunky 5DTemple Enemy: Second Left": 14041809, + "Aztec Chunky 5DTemple Enemy: Reward/Aztec Chunky 5DTemple Enemy: Reward": 14041810, + "Aztec Llama Temple Enemy: Kong Free Instrument/Aztec Llama Temple Enemy: Kong Free Instrument": 14041811, + "Aztec Llama Temple Enemy: Dino Instrument/Aztec Llama Temple Enemy: Dino Instrument": 14041812, + "Aztec Llama Temple Enemy: Matching (0)/Aztec Llama Temple Enemy: Matching0": 14041813, + "Aztec Llama Temple Enemy: Matching (1)/Aztec Llama Temple Enemy: Matching1": 14041814, + "Aztec Llama Temple Enemy: Right/Aztec Llama Temple Enemy: Right": 14041815, + "Aztec Llama Temple Enemy: Left/Aztec Llama Temple Enemy: Left": 14041816, + "Aztec Llama Temple Enemy: Melon Crate/Aztec Llama Temple Enemy: Melon Crate": 14041817, + "Aztec Llama Temple Enemy: Slam Switch/Aztec Llama Temple Enemy: Slam Switch": 14041818, + "Aztec Tiny Temple Enemy: Guard Rotating (0)/Aztec Tiny Temple Enemy: Guard Rotating (0)": 14041819, + "Aztec Tiny Temple Enemy: Guard Rotating (1)/Aztec Tiny Temple Enemy: Guard Rotating (1)": 14041820, + "Aztec Tiny Temple Enemy: Main Room (0)/Aztec Tiny Temple Enemy: Main Room (0)": 14041821, + "Aztec Tiny Temple Enemy: Main Room (1)/Aztec Tiny Temple Enemy: Main Room (1)": 14041822, + "Aztec Tiny Temple Enemy: Main Room (2)/Aztec Tiny Temple Enemy: Main Room (2)": 14041823, + "Aztec Tiny Temple Enemy: Kong Room (0)/Aztec Tiny Temple Enemy: Kong Room (0)": 14041824, + "Aztec Tiny Temple Enemy: Kong Room (1)/Aztec Tiny Temple Enemy: Kong Room (1)": 14041825, + "Aztec Tiny Temple Enemy: Kong Room (2)/Aztec Tiny Temple Enemy: Kong Room (2)": 14041826, + "Aztec Tiny Temple Enemy: Kong Room (3)/Aztec Tiny Temple Enemy: Kong Room (3)": 14041827, + "Aztec Tiny Temple Enemy: Kong Room (4)/Aztec Tiny Temple Enemy: Kong Room (4)": 14041828, + "Frantic Factory Enemy: Candy Cranky (0)/Factory Enemy: Candy Cranky (0)": 14041829, + "Frantic Factory Enemy: Candy Cranky (1)/Factory Enemy: Candy Cranky (1)": 14041830, + "Frantic Factory Enemy: Lobby Left/Factory Enemy: Lobby Left": 14041831, + "Frantic Factory Enemy: Lobby Right/Factory Enemy: Lobby Right": 14041832, + "Frantic Factory Enemy: Storage Room/Factory Enemy: Storage Room": 14041833, + "Frantic Factory Enemy: Block Tower (0)/Factory Enemy: Block Tower (0)": 14041834, + "Frantic Factory Enemy: Block Tower (1)/Factory Enemy: Block Tower (1)": 14041835, + "Frantic Factory Enemy: Block Tower (2)/Factory Enemy: Block Tower (2)": 14041836, + "Frantic Factory Enemy: Tunnel To Hatch/Factory Enemy: Tunnel To Hatch": 14041837, + "Frantic Factory Enemy: Tunnel To Prod (0)/Factory Enemy: Tunnel To Prod (0)": 14041838, + "Frantic Factory Enemy: Tunnel To Prod (1)/Factory Enemy: Tunnel To Prod (1)": 14041839, + "Frantic Factory Enemy: Tunnel To Block Tower/Factory Enemy: Tunnel To Block Tower": 14041840, + "Frantic Factory Enemy: Tunnel To Race (0)/Factory Enemy: Tunnel To Race (0)": 14041841, + "Frantic Factory Enemy: Tunnel To Race (1)/Factory Enemy: Tunnel To Race (1)": 14041842, + "Frantic Factory Enemy: Low Warp 4/Factory Enemy: Low Warp 4": 14041843, + "Frantic Factory Enemy: Diddy Switch/Factory Enemy: Diddy Switch": 14041844, + "Frantic Factory Enemy: To Block Tower Tunnel/Factory Enemy: To Block Tower Tunnel": 14041845, + "Frantic Factory Enemy: Dark Room (0)/Factory Enemy: Dark Room (0)": 14041846, + "Frantic Factory Enemy: Dark Room (1)/Factory Enemy: Dark Room (1)": 14041847, + "Frantic Factory Lobby Enemy: Enemy (0)/Isles Factory Lobby Enemy: Enemy (0)": 14041848, + "Gloomy Galleon Enemy: Chest Room (0)/Galleon Enemy: Chest Room (0)": 14041849, + "Gloomy Galleon Enemy: Chest Room (1)/Galleon Enemy: Chest Room (1)": 14041850, + "Gloomy Galleon Enemy: Near Vine Cannon/Galleon Enemy: Near Vine Cannon": 14041851, + "Gloomy Galleon Enemy: Cranky Cannon/Galleon Enemy: Cranky Cannon": 14041852, + "Gloomy Galleon Enemy: Peanut Tunnel/Galleon Enemy: Peanut Tunnel": 14041853, + "Gloomy Galleon Enemy: Coconut Tunnel/Galleon Enemy: Coconut Tunnel": 14041854, "Lighthouse/Galleon Lighthouse Enemy: Enemy (0)": 14041855, "Lighthouse/Galleon Lighthouse Enemy: Enemy (1)": 14041856, - "Fungi Forest Enemy: Hollow Tree (0)/Enemy": 14041857, - "Fungi Forest Enemy: Hollow Tree (1)/Enemy": 14041858, - "Fungi Forest Enemy: Hollow Tree Entrance/Enemy": 14041859, - "Fungi Forest Enemy: Tree Melon Crate (0)/Enemy": 14041860, - "Fungi Forest Enemy: Tree Melon Crate (1)/Enemy": 14041861, - "Fungi Forest Enemy: Tree Melon Crate (2)/Enemy": 14041862, - "Fungi Forest Enemy: Apple Gauntlet (0)/Enemy": 14041863, - "Fungi Forest Enemy: Apple Gauntlet (1)/Enemy": 14041864, - "Fungi Forest Enemy: Apple Gauntlet (2)/Enemy": 14041865, - "Fungi Forest Enemy: Apple Gauntlet (3)/Enemy": 14041866, - "Fungi Forest Enemy: Near Beanstalk (0)/Enemy": 14041867, - "Fungi Forest Enemy: Near Beanstalk (1)/Enemy": 14041868, - "Fungi Forest Enemy: Green Tunnel/Enemy": 14041869, - "Fungi Forest Enemy: Near Low Warp 5/Enemy": 14041870, - "Fungi Forest Enemy: Near Pink Tunnel Bounce Tag/Enemy": 14041871, - "Fungi Forest Enemy: Near Giant Mushroom Rocketbarrel/Enemy": 14041872, - "Fungi Forest Enemy: Between Yellow Tunnel And RB/Enemy": 14041873, - "Fungi Forest Enemy: Near Cranky/Enemy": 14041874, - "Fungi Forest Enemy: Near Pink Tunnel Giant Mushroom/Enemy": 14041875, - "Fungi Forest Enemy: Giant Mushroom Rear Tag/Enemy": 14041876, - "Fungi Forest Enemy: Near Face Puzzle/Enemy": 14041877, - "Fungi Forest Enemy: Near Crown/Enemy": 14041878, - "Fungi Forest Enemy: Near High Warp 5/Enemy": 14041879, - "Fungi Forest Enemy: Top Of Mushroom/Enemy": 14041880, - "Fungi Forest Enemy: Near Apple Dropoff/Enemy": 14041881, - "Fungi Forest Enemy: Near DKPortal/Enemy": 14041882, - "Fungi Forest Enemy: Near Well Tag/Enemy": 14041883, - "Fungi Forest Enemy: Yellow Tunnel (0)/Enemy": 14041884, - "Fungi Forest Enemy: Yellow Tunnel (1)/Enemy": 14041885, - "Fungi Forest Enemy: Yellow Tunnel (2)/Enemy": 14041886, - "Fungi Forest Enemy: Yellow Tunnel (3)/Enemy": 14041887, - "Fungi Forest Enemy: Near Snide/Enemy": 14041888, - "Fungi Forest Enemy: Near the hidden Rainbow Coin/Enemy": 14041889, - "Fungi Forest Enemy: Near BBlast/Enemy": 14041890, - "Fungi Forest Enemy: Near Dark Attic/Enemy": 14041891, - "Fungi Forest Enemy: Near Well Exit/Enemy": 14041892, - "Fungi Forest Enemy: Near Blue Tunnel/Enemy": 14041893, - "Fungi Forest Enemy: Thornvine (0)/Enemy": 14041894, - "Fungi Forest Enemy: Thornvine (1)/Enemy": 14041895, - "Fungi Forest Enemy: Thornvine (2)/Enemy": 14041896, - "Fungi Forest Enemy: Thornvine Entrance/Enemy": 14041897, + "Fungi Forest Enemy: Hollow Tree (0)/Forest Enemy: Hollow Tree (0)": 14041857, + "Fungi Forest Enemy: Hollow Tree (1)/Forest Enemy: Hollow Tree (1)": 14041858, + "Fungi Forest Enemy: Hollow Tree Entrance/Forest Enemy: Hollow Tree Entrance": 14041859, + "Fungi Forest Enemy: Tree Melon Crate (0)/Forest Enemy: Tree Melon Crate (0)": 14041860, + "Fungi Forest Enemy: Tree Melon Crate (1)/Forest Enemy: Tree Melon Crate (1)": 14041861, + "Fungi Forest Enemy: Tree Melon Crate (2)/Forest Enemy: Tree Melon Crate (2)": 14041862, + "Fungi Forest Enemy: Apple Gauntlet (0)/Forest Enemy: Apple Gauntlet (0)": 14041863, + "Fungi Forest Enemy: Apple Gauntlet (1)/Forest Enemy: Apple Gauntlet (1)": 14041864, + "Fungi Forest Enemy: Apple Gauntlet (2)/Forest Enemy: Apple Gauntlet (2)": 14041865, + "Fungi Forest Enemy: Apple Gauntlet (3)/Forest Enemy: Apple Gauntlet (3)": 14041866, + "Fungi Forest Enemy: Near Beanstalk (0)/Forest Enemy: Near Beanstalk (0)": 14041867, + "Fungi Forest Enemy: Near Beanstalk (1)/Forest Enemy: Near Beanstalk (1)": 14041868, + "Fungi Forest Enemy: Green Tunnel/Forest Enemy: Green Tunnel": 14041869, + "Fungi Forest Enemy: Near Low Warp 5/Forest Enemy: Near Low Warp 5": 14041870, + "Fungi Forest Enemy: Near Pink Tunnel Bounce Tag/Forest Enemy: Near Pink Tunnel Bounce Tag": 14041871, + "Fungi Forest Enemy: Near Giant Mushroom Rocketbarrel/Forest Enemy: Near Giant Mushroom Rocketbarrel": 14041872, + "Fungi Forest Enemy: Between Yellow Tunnel And RB/Forest Enemy: Between Yellow Tunnel And RB": 14041873, + "Fungi Forest Enemy: Near Cranky/Forest Enemy: Near Cranky": 14041874, + "Fungi Forest Enemy: Near Pink Tunnel Giant Mushroom/Forest Enemy: Near Pink Tunnel Giant Mushroom": 14041875, + "Fungi Forest Enemy: Giant Mushroom Rear Tag/Forest Enemy: Giant Mushroom Rear Tag": 14041876, + "Fungi Forest Enemy: Near Face Puzzle/Forest Enemy: Near Face Puzzle": 14041877, + "Fungi Forest Enemy: Near Crown/Forest Enemy: Near Crown": 14041878, + "Fungi Forest Enemy: Near High Warp 5/Forest Enemy: Near High Warp 5": 14041879, + "Fungi Forest Enemy: Top Of Mushroom/Forest Enemy: Top Of Mushroom": 14041880, + "Fungi Forest Enemy: Near Apple Dropoff/Forest Enemy: Near Apple Dropoff": 14041881, + "Fungi Forest Enemy: Near DKPortal/Forest Enemy: Near DKPortal": 14041882, + "Fungi Forest Enemy: Near Well Tag/Forest Enemy: Near Well Tag": 14041883, + "Fungi Forest Enemy: Yellow Tunnel (0)/Forest Enemy: Yellow Tunnel (0)": 14041884, + "Fungi Forest Enemy: Yellow Tunnel (1)/Forest Enemy: Yellow Tunnel (1)": 14041885, + "Fungi Forest Enemy: Yellow Tunnel (2)/Forest Enemy: Yellow Tunnel (2)": 14041886, + "Fungi Forest Enemy: Yellow Tunnel (3)/Forest Enemy: Yellow Tunnel (3)": 14041887, + "Fungi Forest Enemy: Near Snide/Forest Enemy: Near Snide": 14041888, + "Fungi Forest Enemy: Near the hidden Rainbow Coin/Forest Enemy: Near the hidden Rainbow Coin": 14041889, + "Fungi Forest Enemy: Near BBlast/Forest Enemy: Near BBlast": 14041890, + "Fungi Forest Enemy: Near Dark Attic/Forest Enemy: Near Dark Attic": 14041891, + "Fungi Forest Enemy: Near Well Exit/Forest Enemy: Near Well Exit": 14041892, + "Fungi Forest Enemy: Near Blue Tunnel/Forest Enemy: Near Blue Tunnel": 14041893, + "Fungi Forest Enemy: Thornvine (0)/Forest Enemy: Thornvine (0)": 14041894, + "Fungi Forest Enemy: Thornvine (1)/Forest Enemy: Thornvine (1)": 14041895, + "Fungi Forest Enemy: Thornvine (2)/Forest Enemy: Thornvine (2)": 14041896, + "Fungi Forest Enemy: Thornvine Entrance/Forest Enemy: Thornvine Entrance": 14041897, "Forest Anthill/Forest Anthill Enemy: Gauntlet (0)": 14041898, "Forest Anthill/Forest Anthill Enemy: Gauntlet (1)": 14041899, "Forest Anthill/Forest Anthill Enemy: Gauntlet (2)": 14041900, "Forest Anthill/Forest Anthill Enemy: Gauntlet (3)": 14041901, "Winch Room/Forest Winch Room Enemy: Enemy": 14041902, - "Forest Thornvine Barn Enemy: Enemy/Enemy": 14041903, - "Forest Mill Front Enemy: Enemy/Enemy": 14041904, - "Forest Mill Back Enemy: Enemy/Enemy": 14041905, + "Forest Thornvine Barn Enemy: Enemy/Forest Thornvine Barn Enemy: Enemy": 14041903, + "Forest Mill Front Enemy: Enemy/Forest Mill Front Enemy: Enemy": 14041904, + "Forest Mill Back Enemy: Enemy/Forest Mill Back Enemy: Enemy": 14041905, "Inside the Mushroom/Forest Giant Mushroom Enemy: Above Night Door": 14041906, "Inside the Mushroom/Forest Giant Mushroom Enemy: Path (0)": 14041907, "Inside the Mushroom/Forest Giant Mushroom Enemy: Path (1)": 14041908, "Zinger Room/Forest Lanky Zingers Room Enemy: Enemy (0)": 14041909, "Zinger Room/Forest Lanky Zingers Room Enemy: Enemy (1)": 14041910, "Face Puzzle Room/Forest Chunky Face Room Enemy: Enemy": 14041911, - "Crystal Caves Enemy: Start/Enemy": 14041912, - "Crystal Caves Enemy: Near Ice Castle/Enemy": 14041913, - "Crystal Caves Enemy: Outside 5DC/Enemy": 14041914, - "Crystal Caves Enemy: 1DC Waterfall/Enemy": 14041915, - "Crystal Caves Enemy: Near Funky/Enemy": 14041916, - "Crystal Caves Enemy: Near Snide/Enemy": 14041917, - "Crystal Caves Enemy: Near Bonus Room/Enemy": 14041918, - "Crystal Caves Enemy: 1DC Headphones/Enemy": 14041919, + "Crystal Caves Enemy: Start/Caves Enemy: Start": 14041912, + "Crystal Caves Enemy: Near Ice Castle/Caves Enemy: Near Ice Castle": 14041913, + "Crystal Caves Enemy: Outside 5DC/Caves Enemy: Outside 5DC": 14041914, + "Crystal Caves Enemy: 1DC Waterfall/Caves Enemy: 1DC Waterfall": 14041915, + "Crystal Caves Enemy: Near Funky/Caves Enemy: Near Funky": 14041916, + "Crystal Caves Enemy: Near Snide/Caves Enemy: Near Snide": 14041917, + "Crystal Caves Enemy: Near Bonus Room/Caves Enemy: Near Bonus Room": 14041918, + "Crystal Caves Enemy: 1DC Headphones/Caves Enemy: 1DC Headphones": 14041919, "Caves DK 5 Door Igloo/Caves Donkey Igloo Enemy: Right": 14041920, "Caves DK 5 Door Igloo/Caves Donkey Igloo Enemy: Left": 14041921, "Caves Tiny 5 Door Igloo/Caves Tiny Igloo Enemy: Big Enemy": 14041922, "Caves Lanky Sprint Cabin/Caves Lanky Cabin Enemy: Near": 14041923, - "Creepy Castle Enemy: Near Bridge (0)/Enemy": 14041924, - "Creepy Castle Enemy: Near Bridge (1)/Enemy": 14041925, - "Creepy Castle Enemy: Wooden Extrusion (0)/Enemy": 14041926, - "Creepy Castle Enemy: Wooden Extrusion (1)/Enemy": 14041927, - "Creepy Castle Enemy: Near Shed/Enemy": 14041928, - "Creepy Castle Enemy: Near Library/Enemy": 14041929, - "Creepy Castle Enemy: Near Tower/Enemy": 14041930, - "Creepy Castle Enemy: Museum Steps/Enemy": 14041931, - "Creepy Castle Enemy: Near Low Cave/Enemy": 14041932, - "Creepy Castle Enemy: Path To Low Kasplat/Enemy": 14041933, - "Creepy Castle Enemy: Low TnS/Enemy": 14041934, - "Creepy Castle Enemy: Path To Dungeon/Enemy": 14041935, - "Creepy Castle Enemy: Near Headphones/Enemy": 14041936, - "Creepy Castle Lobby Enemy: Left/Enemy": 14041937, - "Creepy Castle Lobby Enemy: Far Right/Enemy": 14041938, - "Creepy Castle Lobby Enemy: Near Right/Enemy": 14041939, - "Castle Ballroom Enemy: Start/Enemy": 14041940, - "Castle Dungeon Enemy: Face Room/Enemy": 14041941, - "Castle Dungeon Enemy: Chair Room/Enemy": 14041942, - "Castle Dungeon Enemy: Outside Lanky Room/Enemy": 14041943, - "Castle Lower Cave Enemy: Near Crypt/Enemy": 14041944, - "Castle Lower Cave Enemy: Stair Right/Enemy": 14041945, - "Castle Lower Cave Enemy: Stair Left/Enemy": 14041946, - "Castle Lower Cave Enemy: Near Mausoleum/Enemy": 14041947, - "Castle Lower Cave Enemy: Near Funky/Enemy": 14041948, - "Castle Lower Cave Enemy: Near Tag/Enemy": 14041949, + "Creepy Castle Enemy: Near Bridge (0)/Castle Enemy: Near Bridge (0)": 14041924, + "Creepy Castle Enemy: Near Bridge (1)/Castle Enemy: Near Bridge (1)": 14041925, + "Creepy Castle Enemy: Wooden Extrusion (0)/Castle Enemy: Wooden Extrusion (0)": 14041926, + "Creepy Castle Enemy: Wooden Extrusion (1)/Castle Enemy: Wooden Extrusion (1)": 14041927, + "Creepy Castle Enemy: Near Shed/Castle Enemy: Near Shed": 14041928, + "Creepy Castle Enemy: Near Library/Castle Enemy: Near Library": 14041929, + "Creepy Castle Enemy: Near Tower/Castle Enemy: Near Tower": 14041930, + "Creepy Castle Enemy: Museum Steps/Castle Enemy: Museum Steps": 14041931, + "Creepy Castle Enemy: Near Low Cave/Castle Enemy: Near Low Cave": 14041932, + "Creepy Castle Enemy: Path To Low Kasplat/Castle Enemy: Path To Low Kasplat": 14041933, + "Creepy Castle Enemy: Low TnS/Castle Enemy: Low TnS": 14041934, + "Creepy Castle Enemy: Path To Dungeon/Castle Enemy: Path To Dungeon": 14041935, + "Creepy Castle Enemy: Near Headphones/Castle Enemy: Near Headphones": 14041936, + "Creepy Castle Lobby Enemy: Left/Isles Castle Lobby Enemy: Left": 14041937, + "Creepy Castle Lobby Enemy: Far Right/Isles Castle Lobby Enemy: Far Right": 14041938, + "Creepy Castle Lobby Enemy: Near Right/Isles Castle Lobby Enemy: Near Right": 14041939, + "Castle Ballroom Enemy: Start/Castle Ballroom Enemy: Start": 14041940, + "Castle Dungeon Enemy: Face Room/Castle Dungeon Enemy: Face Room": 14041941, + "Castle Dungeon Enemy: Chair Room/Castle Dungeon Enemy: Chair Room": 14041942, + "Castle Dungeon Enemy: Outside Lanky Room/Castle Dungeon Enemy: Outside Lanky Room": 14041943, + "Castle Lower Cave Enemy: Near Crypt/Castle Lower Cave Enemy: Near Crypt": 14041944, + "Castle Lower Cave Enemy: Stair Right/Castle Lower Cave Enemy: Stair Right": 14041945, + "Castle Lower Cave Enemy: Stair Left/Castle Lower Cave Enemy: Stair Left": 14041946, + "Castle Lower Cave Enemy: Near Mausoleum/Castle Lower Cave Enemy: Near Mausoleum": 14041947, + "Castle Lower Cave Enemy: Near Funky/Castle Lower Cave Enemy: Near Funky": 14041948, + "Castle Lower Cave Enemy: Near Tag/Castle Lower Cave Enemy: Near Tag": 14041949, "Castle Diddy Crypt/Castle Crypt Enemy: Diddy Coffin (0)": 14041950, "Castle Diddy Crypt/Castle Crypt Enemy: Diddy Coffin (1)": 14041951, "Castle Diddy Crypt/Castle Crypt Enemy: Diddy Coffin (2)": 14041952, @@ -552,325 +858,90 @@ def dk64_map_to_tab_index(data: Any) -> int: "Castle Chunky Crypt/Castle Crypt Enemy: Chunky Coffin (2)": 14041956, "Castle Chunky Crypt/Castle Crypt Enemy: Chunky Coffin (3)": 14041957, "Castle DK Minecart/Castle Crypt Enemy: Minecart Entry": 14041958, - "Castle Crypt Enemy: Fork/Enemy": 14041959, - "Castle Crypt Enemy: Near Diddy/Enemy": 14041960, - "Castle Crypt Enemy: Near Chunky/Enemy": 14041961, + "Castle Crypt Enemy: Fork/Castle Crypt Enemy: Fork": 14041959, + "Castle Crypt Enemy: Near Diddy/Castle Crypt Enemy: Near Diddy": 14041960, + "Castle Crypt Enemy: Near Chunky/Castle Crypt Enemy: Near Chunky": 14041961, "Mausoleum/Castle Mausoleum Enemy: Tiny Path": 14041962, "Mausoleum/Castle Mausoleum Enemy: Lanky Path (0)": 14041963, "Mausoleum/Castle Mausoleum Enemy: Lanky Path (1)": 14041964, - "Castle Upper Cave Enemy: Near Dungeon/Enemy": 14041965, - "Castle Upper Cave Enemy: Near Pit/Enemy": 14041966, - "Castle Upper Cave Enemy: Near Entrance/Enemy": 14041967, + "Castle Upper Cave Enemy: Near Dungeon/Castle Upper Cave Enemy: Near Dungeon": 14041965, + "Castle Upper Cave Enemy: Near Pit/Castle Upper Cave Enemy: Near Pit": 14041966, + "Castle Upper Cave Enemy: Near Entrance/Castle Upper Cave Enemy: Near Entrance": 14041967, "Castle DK Library/Castle Library Enemy: Fork Left (0)": 14041968, "Castle DK Library/Castle Library Enemy: Fork Left (1)": 14041969, "Castle DK Library/Castle Library Enemy: Fork Center": 14041970, "Castle DK Library/Castle Library Enemy: Fork Right": 14041971, - "Castle Museum Enemy: Main Floor (0)/Enemy": 14041972, - "Castle Museum Enemy: Main Floor (1)/Enemy": 14041973, - "Castle Museum Enemy: Main Floor (2)/Enemy": 14041974, - "Castle Museum Enemy: Main Floor (3)/Enemy": 14041975, - "Castle Museum Enemy: Start/Enemy": 14041976, + "Castle Museum Enemy: Main Floor (0)/Castle Museum Enemy: Main Floor (0)": 14041972, + "Castle Museum Enemy: Main Floor (1)/Castle Museum Enemy: Main Floor (1)": 14041973, + "Castle Museum Enemy: Main Floor (2)/Castle Museum Enemy: Main Floor (2)": 14041974, + "Castle Museum Enemy: Main Floor (3)/Castle Museum Enemy: Main Floor (3)": 14041975, + "Castle Museum Enemy: Start/Castle Museum Enemy: Start": 14041976, "Inside the Tree/Castle Tree Enemy: Start Room (0)": 14041977, "Inside the Tree/Castle Tree Enemy: Start Room (1)": 14041978, - "Hideout Helm Enemy: Start (0)/Enemy": 14041979, - "Hideout Helm Enemy: Start (1)/Enemy": 14041980, - "Hideout Helm Enemy: Hill/Enemy": 14041981, - "Hideout Helm Enemy: Switch Room (0)/Enemy": 14041982, - "Hideout Helm Enemy: Switch Room (1)/Enemy": 14041983, - "Hideout Helm Enemy: Mini Room (0)/Enemy": 14041984, - "Hideout Helm Enemy: Mini Room (1)/Enemy": 14041985, - "Hideout Helm Enemy: Mini Room (2)/Enemy": 14041986, - "Hideout Helm Enemy: Mini Room (3)/Enemy": 14041987, - "Hideout Helm Enemy: DKRoom/Enemy": 14041988, - "Hideout Helm Enemy: Chunky Room (0)/Enemy": 14041989, - "Hideout Helm Enemy: Chunky Room (1)/Enemy": 14041990, - "Hideout Helm Enemy: Tiny Room/Enemy": 14041991, - "Hideout Helm Enemy: Lanky Room (0)/Enemy": 14041992, - "Hideout Helm Enemy: Lanky Room (1)/Enemy": 14041993, - "Hideout Helm Enemy: Diddy Room (0)/Enemy": 14041994, - "Hideout Helm Enemy: Diddy Room (1)/Enemy": 14041995, - "Hideout Helm Enemy: Nav Right/Enemy": 14041996, - "Hideout Helm Enemy: Nav Left/Enemy": 14041997, - "Isles Enemy: Pineapple Cage (0)/Enemy": 14041998, - "Isles Enemy: Fungi Cannon (0)/Enemy": 14041999, - "Jungle Japes Lobby Enemy: Enemy (0)/Enemy": 14041738, - "Jungle Japes Lobby Enemy: Enemy (1)/Enemy": 14041739, - "Isles Enemy: Japes Entrance/Enemy": 14042000, - "Isles Enemy: Monkeyport Pad/Enemy": 14042001, - "Isles Enemy: Upper Factory Path/Enemy": 14042002, - "Isles Enemy: Near Aztec/Enemy": 14042003, - "Isles Enemy: Fungi Cannon (1)/Enemy": 14042004, - "Isles Enemy: Pineapple Cage (1)/Enemy": 14042005, - "Isles Enemy: Lower Factory Path (0)/Enemy": 14042006, - "Isles Enemy: Lower Factory Path (1)/Enemy": 14042007, - "Isles Boulder: Near Level 2/Boulder": 14041702, - "Isles Chunky Triangle Pad/Isles Boulder: Near Level 6": 14041703, - "Aztec Boulder: Tunnel/Boulder": 14041704, - "Caves Boulder: Small/Boulder": 14041705, - "Caves Boulder: Large/Boulder": 14041706, - "Castle Boulder: Museum/Boulder": 14041707, - "Isles Lanky Instrument Pad/Isles Boulder: Japes Lobby": 14041708, - "Isles Boulder: Castle Lobby/Boulder": 14041709, - "Isles Boulder: Caves Lobby/Boulder": 14041710, - "Forest Keg: Mill Front Near/Boulder": 14041711, - "Forest Keg: Mill Front Far/Boulder": 14041712, - "Forest Keg: Mill Back/Boulder": 14041713, - "Aztec Chunky Vases/Aztec Vase: Circle": 14041714, - "Aztec Chunky Vases/Aztec Vase: Colon": 14041715, - "Aztec Chunky Vases/Aztec Vase: Triangle": 14041716, - "Aztec Chunky Vases/Aztec Vase: Plus": 14041717, - "Medals/Factory DK Medal": 14041245, - "Medals/Factory Diddy Medal": 14041246, - "Medals/Factory Lanky Medal": 14041247, - "Medals/Factory Tiny Medal": 14041248, - "Medals/Factory Chunky Medal": 14041249, - "Medals/Factory DK Half-Medal": 14042339, - "Medals/Factory Diddy Half-Medal": 14042340, - "Medals/Factory Lanky Half-Medal": 14042341, - "Medals/Factory Tiny Half-Medal": 14042342, - "Medals/Factory Chunky Half-Medal": 14042343, - "Medals/Boss": 14041280, - "Factory DK Number Game/Golden Banana": 14041250, - "Factory Diddy Block Tower/Golden Banana": 14041251, - "Factory Lanky Testing Room Barrel/Golden Banana": 14041252, - "Factory Tiny Dartboard/Golden Banana": 14041253, - "Factory Kasplat: Block Tower/Kasplat": 14041254, - "Factory Fairy (Number Game)/Fairy": 14041255, - "Factory Fairy (Near Funky's)/Fairy": 14041256, - "Factory Crate: Near Funky/Crate": 14041692, - "Factory Diddy Charge Enemies/Golden Banana": 14041257, - "Factory Chunky Toy Monster/Golden Banana": 14041259, - "Factory Kasplat: R&D/Kasplat": 14041260, - "Factory Battle Arena (Under Grate)/Crown": 14041261, - "Factory Lanky Piano Game/Golden Banana": 14041258, - "Factory Tiny Car Race/Golden Banana": 14041262, - "Factory Diddy Storage Room Barrel/Golden Banana": 14041263, - "Factory DK Power Hut/Golden Banana": 14041264, - "Chunky's Cage/Chunky Kong's Cage": 14041265, - "Chunky's Cage/Factory Free Chunky Item": 14041268, - "Factory Chunky Dark Room/Golden Banana": 14041270, - "Factory Dirt: Dark Room/Rainbow Coin": 14041675, - "Factory Kasplat: Pole to Arcade/Kasplat": 14041273, - "Factory Crate: Near Candy/Crate": 14041693, - "Factory DK Blast Course/Golden Banana": 14041267, - "Factory Tiny Mini by Arcade/Golden Banana": 14041269, - "Factory Chunky Barrel by Arcade/Golden Banana": 14041271, - "DK Arcade/Round 2": 14041266, - "Factory Kasplat: Base of Production/Kasplat": 14041272, - "Factory DK Crusher Room/Golden Banana": 14041274, - "Factory Chunky Production Timer/Golden Banana": 14041278, - "Factory Diddy Production Spring/Golden Banana": 14041275, - "Factory Lanky Production Handstand/Golden Banana": 14041276, - "Factory Tiny Production Twirl/Golden Banana": 14041277, - "Factory Kasplat: Upper Production Pipe/Kasplat": 14041279, - "Medals/Galleon DK Medal": 14041281, - "Medals/Galleon Diddy Medal": 14041282, - "Medals/Galleon Lanky Medal": 14041283, - "Medals/Galleon Tiny Medal": 14041284, - "Medals/Galleon Chunky Medal": 14041285, - "Medals/Galleon DK Half-Medal": 14042344, - "Medals/Galleon Diddy Half-Medal": 14042345, - "Medals/Galleon Lanky Half-Medal": 14042346, - "Medals/Galleon Tiny Half-Medal": 14042347, - "Medals/Galleon Chunky Half-Medal": 14042348, - "Medals/Boss": 14041319, - "Galleon Chunky Chest/Golden Banana": 14041286, - "Galleon Battle Arena (Under Cranky)/Crown": 14041288, - "Galleon Fairy (In Punch Chest)/Fairy": 14041289, - "Galleon Kasplat: Past Vines/Kasplat": 14041287, - "Galleon Chunky Cannon Game/Golden Banana": 14041290, - "Galleon Kasplat: Cannon Game Room/Kasplat": 14041291, - "Galleon Kasplat: Lighthouse Alcove/Kasplat": 14041294, - "Galleon Diddy Top of Lighthouse/Golden Banana": 14041292, - "Galleon Lanky Enguarde Chest/Golden Banana": 14041293, - "Lighthouse/Galleon Dirt: Lighthouse": 14041682, - "Lighthouse/Galleon DK Lighthouse": 14041295, - "Galleon Tiny Mermaid Reward/Golden Banana": 14041296, - "Galleon Chunky Seasick/Golden Banana": 14041297, - "Galleon Seal/Free the Seal": 14041298, - "Galleon Kasplat: Musical Cactus/Kasplat": 14041299, - "Galleon Crate: Near Cactus/Crate": 14041694, - "Galleon Seal/Seal Race": 14041300, - "Galleon Lanky Gold Tower Barrel/Golden Banana": 14041302, - "Galleon Diddy Gold Tower Barrel/Golden Banana": 14041301, - "Galleon Kasplat: Diddy Gold Tower/Kasplat": 14041303, - "Treasure Chest/Treasure Chest Far Left Clam": 14041314, - "Treasure Chest/Treasure Chest Center Clam": 14041315, - "Treasure Chest/Treasure Chest Far Right Clam": 14041316, - "Treasure Chest/Treasure Chest Close Right Clam": 14041317, - "Treasure Chest/Treasure Chest Close Left Clam": 14041318, - "Galleon Tiny Submarine Barrel/Golden Banana": 14041304, - "Galleon Diddy Mechfish/Golden Banana": 14041305, - "2-Door Ship/Lanky 2DS": 14041306, - "2-Door Ship/Tiny 2DS": 14041307, - "Galleon DK 5-Door Ship/Golden Banana": 14041308, - "Galleon Diddy 5-Door Ship/Golden Banana": 14041309, - "Galleon Lanky 5-Door Ship/Golden Banana": 14041310, - "Galleon Tiny 5-Door Ship/Golden Banana": 14041311, - "Galleon Tiny 5-Door Ship/Fairy": 14041312, - "Galleon Chunky 5-Door Ship/Golden Banana": 14041313, - "Japes Funky/Funky DK": 14041448, - "Japes Funky/Funky Diddy": 14041449, - "Japes Funky/Funky Lanky": 14041450, - "Japes Funky/Funky Tiny": 14041451, - "Japes Funky/Funky Chunky": 14041452, - "Aztec Funky/Funky DK": 14041485, - "Aztec Funky/Funky Diddy": 14041486, - "Aztec Funky/Funky Lanky": 14041487, - "Aztec Funky/Funky Tiny": 14041488, - "Aztec Funky/Funky Chunky": 14041489, - "Factory Funky/Funky DK": 14041492, - "Factory Funky/Funky Diddy": 14041493, - "Factory Funky/Funky Lanky": 14041494, - "Factory Funky/Funky Tiny": 14041495, - "Factory Funky/Funky Chunky": 14041496, - "Galleon Funky/Funky DK": 14041510, - "Galleon Funky/Funky Diddy": 14041511, - "Galleon Funky/Funky Lanky": 14041512, - "Galleon Funky/Funky Tiny": 14041513, - "Galleon Funky/Funky Chunky": 14041514, - "Forest Funky/Funky DK": 14041525, - "Forest Funky/Funky Diddy": 14041526, - "Forest Funky/Funky Lanky": 14041527, - "Forest Funky/Funky Tiny": 14041528, - "Forest Funky/Funky Chunky": 14041529, - "Caves Funky/Funky DK": 14041533, - "Caves Funky/Funky Diddy": 14041534, - "Caves Funky/Funky Lanky": 14041535, - "Caves Funky/Funky Tiny": 14041536, - "Caves Funky/Funky Chunky": 14041537, - "Castle Funky/Funky DK": 14041548, - "Castle Funky/Funky Diddy": 14041549, - "Castle Funky/Funky Lanky": 14041550, - "Castle Funky/Funky Tiny": 14041551, - "Castle Funky/Funky Chunky": 14041552, - "Aztec Candy/Candy DK": 14041455, - "Aztec Candy/Candy Diddy": 14041456, - "Aztec Candy/Candy Lanky": 14041457, - "Aztec Candy/Candy Tiny": 14041458, - "Aztec Candy/Candy Chunky": 14041459, - "Factory Candy/Candy DK": 14041498, - "Factory Candy/Candy Diddy": 14041499, - "Factory Candy/Candy Lanky": 14041500, - "Factory Candy/Candy Tiny": 14041501, - "Factory Candy/Candy Chunky": 14041502, - "Galleon Candy/Candy DK": 14041515, - "Galleon Candy/Candy Diddy": 14041516, - "Galleon Candy/Candy Lanky": 14041517, - "Galleon Candy/Candy Tiny": 14041518, - "Galleon Candy/Candy Chunky": 14041519, - "Caves Candy/Candy DK": 14041538, - "Caves Candy/Candy Diddy": 14041539, - "Caves Candy/Candy Lanky": 14041540, - "Caves Candy/Candy Tiny": 14041541, - "Caves Candy/Candy Chunky": 14041542, - "Castle Candy/Candy DK": 14041553, - "Castle Candy/Candy Diddy": 14041554, - "Castle Candy/Candy Lanky": 14041555, - "Castle Candy/Candy Tiny": 14041556, - "Castle Candy/Candy Chunky": 14041557, - "Isles Cranky/Jetpac": 14041477, - "Japes Cranky/Cranky DK": 14041443, - "Japes Cranky/Cranky Diddy": 14041444, - "Japes Cranky/Cranky Lanky": 14041445, - "Japes Cranky/Cranky Tiny": 14041446, - "Japes Cranky/Cranky Chunky": 14041447, - "Aztec Cranky/Cranky DK": 14041453, - "Aztec Cranky/Cranky Diddy": 14041454, - "Aztec Cranky/Cranky Lanky": 14041481, - "Aztec Cranky/Cranky Tiny": 14041482, - "Aztec Cranky/Cranky Chunky": 14041483, - "Factory Cranky/Cranky DK": 14041460, - "Factory Cranky/Cranky Diddy": 14041461, - "Factory Cranky/Cranky Lanky": 14041462, - "Factory Cranky/Cranky Tiny": 14041463, - "Factory Cranky/Cranky Chunky": 14041464, - "Galleon Cranky/Cranky DK": 14041504, - "Galleon Cranky/Cranky Diddy": 14041505, - "Galleon Cranky/Cranky Lanky": 14041506, - "Galleon Cranky/Cranky Tiny": 14041507, - "Galleon Cranky/Cranky Chunky": 14041508, - "Forest Cranky/Cranky DK": 14041520, - "Forest Cranky/Cranky Diddy": 14041521, - "Forest Cranky/Cranky Lanky": 14041522, - "Forest Cranky/Cranky Tiny": 14041523, - "Forest Cranky/Cranky Chunky": 14041524, - "Caves Cranky/Cranky Lanky": 14041469, - "Caves Cranky/Cranky Tiny": 14041470, - "Caves Cranky/Cranky Chunky": 14041471, - "Caves Cranky/Cranky DK": 14041531, - "Caves Cranky/Cranky Diddy": 14041532, - "Castle Cranky/Cranky DK": 14041543, - "Castle Cranky/Cranky Diddy": 14041544, - "Castle Cranky/Cranky Lanky": 14041545, - "Castle Cranky/Cranky Tiny": 14041546, - "Castle Cranky/Cranky Chunky": 14041547, - "Isles Cranky/Cranky DK": 14041558, - "Isles Cranky/Cranky Diddy": 14041559, - "Isles Cranky/Cranky Lanky": 14041560, - "Isles Cranky/Cranky Tiny": 14041561, - "Isles Cranky/Cranky Chunky": 14041562, - "Turn in 1 Blueprint/Turn in 1 Blueprint": 14041563, - "Turn in 2 Blueprints/Turn in 2 Blueprints": 14041564, - "Turn in 3 Blueprints/Turn in 3 Blueprints": 14041565, - "Turn in 4 Blueprints/Turn in 4 Blueprints": 14041566, - "Turn in 5 Blueprints/Turn in 5 Blueprints": 14041567, - "Turn in 6 Blueprints/Turn in 6 Blueprints": 14041568, - "Turn in 7 Blueprints/Turn in 7 Blueprints": 14041569, - "Turn in 8 Blueprints/Turn in 8 Blueprints": 14041570, - "Turn in 9 Blueprints/Turn in 9 Blueprints": 14041571, - "Turn in 10 Blueprints/Turn in 10 Blueprints": 14041572, - "Turn in 11 Blueprints/Turn in 11 Blueprints": 14041573, - "Turn in 12 Blueprints/Turn in 12 Blueprints": 14041574, - "Turn in 13 Blueprints/Turn in 13 Blueprints": 14041575, - "Turn in 14 Blueprints/Turn in 14 Blueprints": 14041576, - "Turn in 15 Blueprints/Turn in 15 Blueprints": 14041577, - "Turn in 16 Blueprints/Turn in 16 Blueprints": 14041578, - "Turn in 17 Blueprints/Turn in 17 Blueprints": 14041579, - "Turn in 18 Blueprints/Turn in 18 Blueprints": 14041580, - "Turn in 19 Blueprints/Turn in 19 Blueprints": 14041581, - "Turn in 20 Blueprints/Turn in 20 Blueprints": 14041582, - "Turn in 21 Blueprints/Turn in 21 Blueprints": 14041583, - "Turn in 22 Blueprints/Turn in 22 Blueprints": 14041584, - "Turn in 23 Blueprints/Turn in 23 Blueprints": 14041585, - "Turn in 24 Blueprints/Turn in 24 Blueprints": 14041586, - "Turn in 25 Blueprints/Turn in 25 Blueprints": 14041587, - "Turn in 26 Blueprints/Turn in 26 Blueprints": 14041588, - "Turn in 27 Blueprints/Turn in 27 Blueprints": 14041589, - "Turn in 28 Blueprints/Turn in 28 Blueprints": 14041590, - "Turn in 29 Blueprints/Turn in 29 Blueprints": 14041591, - "Turn in 30 Blueprints/Turn in 30 Blueprints": 14041592, - "Turn in 31 Blueprints/Turn in 31 Blueprints": 14041593, - "Turn in 32 Blueprints/Turn in 32 Blueprints": 14041594, - "Turn in 33 Blueprints/Turn in 33 Blueprints": 14041595, - "Turn in 34 Blueprints/Turn in 34 Blueprints": 14041596, - "Turn in 35 Blueprints/Turn in 35 Blueprints": 14041597, - "Turn in 36 Blueprints/Turn in 36 Blueprints": 14041598, - "Turn in 37 Blueprints/Turn in 37 Blueprints": 14041599, - "Turn in 38 Blueprints/Turn in 38 Blueprints": 14041600, - "Turn in 39 Blueprints/Turn in 39 Blueprints": 14041601, - "Turn in 40 Blueprints/Turn in 40 Blueprints": 14041602, - # Shared Shop Locations - "Isles Cranky/Cranky Shared": 14041442, - "Japes Cranky/Cranky Shared": 14041478, - "Japes Funky/Funky Shared": 14041479, - "Aztec Cranky/Cranky Shared": 14041480, - "Aztec Funky/Funky Shared": 14041484, - "Aztec Candy/Candy Shared": 14041490, - "Factory Cranky/Cranky Shared": 14041491, - "Factory Funky/Funky Shared": 14041465, - "Factory Candy/Candy Shared": 14041497, - "Galleon Cranky/Cranky Shared": 14041503, - "Galleon Funky/Funky Shared": 14041509, - "Galleon Candy/Candy Shared": 14041466, - "Forest Cranky/Cranky Shared": 14041467, - "Forest Funky/Funky Shared": 14041468, - "Caves Cranky/Cranky Shared": 14041530, - "Caves Funky/Funky Shared": 14041472, - "Caves Candy/Candy Shared": 14041473, - "Castle Cranky/Cranky Shared": 14041474, - "Castle Funky/Funky Shared": 14041475, - "Castle Candy/Candy Shared": 14041476, + "Hideout Helm Enemy: Start (0)/Helm Enemy: Start (0)": 14041979, + "Hideout Helm Enemy: Start (1)/Helm Enemy: Start (1)": 14041980, + "Hideout Helm Enemy: Hill/Helm Enemy: Hill": 14041981, + "Hideout Helm Enemy: Switch Room (0)/Helm Enemy: Switch Room (0)": 14041982, + "Hideout Helm Enemy: Switch Room (1)/Helm Enemy: Switch Room (1)": 14041983, + "Hideout Helm Enemy: Mini Room (0)/Helm Enemy: Mini Room (0)": 14041984, + "Hideout Helm Enemy: Mini Room (1)/Helm Enemy: Mini Room (1)": 14041985, + "Hideout Helm Enemy: Mini Room (2)/Helm Enemy: Mini Room (2)": 14041986, + "Hideout Helm Enemy: Mini Room (3)/Helm Enemy: Mini Room (3)": 14041987, + "Hideout Helm Enemy: DKRoom/Helm Enemy: DKRoom": 14041988, + "Hideout Helm Enemy: Chunky Room (0)/Helm Enemy: Chunky Room (0)": 14041989, + "Hideout Helm Enemy: Chunky Room (1)/Helm Enemy: Chunky Room (1)": 14041990, + "Hideout Helm Enemy: Tiny Room/Helm Enemy: Tiny Room": 14041991, + "Hideout Helm Enemy: Lanky Room (0)/Helm Enemy: Lanky Room (0)": 14041992, + "Hideout Helm Enemy: Lanky Room (1)/Helm Enemy: Lanky Room (1)": 14041993, + "Hideout Helm Enemy: Diddy Room (0)/Helm Enemy: Diddy Room (0)": 14041994, + "Hideout Helm Enemy: Diddy Room (1)/Helm Enemy: Diddy Room (1)": 14041995, + "Hideout Helm Enemy: Nav Right/Helm Enemy: Nav Right": 14041996, + "Hideout Helm Enemy: Nav Left/Helm Enemy: Nav Left": 14041997, + "Isles Enemy: Pineapple Cage (0)/Isles Enemy: Pineapple Cage (0)": 14041998, + "Isles Enemy: Fungi Cannon (0)/Isles Enemy: Fungi Cannon (0)": 14041999, + "Isles Enemy: Japes Entrance/Isles Enemy: Japes Entrance": 14042000, + "Isles Enemy: Monkeyport Pad/Isles Enemy: Monkeyport Pad": 14042001, + "Isles Enemy: Upper Factory Path/Isles Enemy: Upper Factory Path": 14042002, + "Isles Enemy: Near Aztec/Isles Enemy: Near Aztec": 14042003, + "Isles Enemy: Fungi Cannon (1)/Isles Enemy: Fungi Cannon (1)": 14042004, + "Isles Enemy: Pineapple Cage (1)/Isles Enemy: Pineapple Cage (1)": 14042005, + "Isles Enemy: Lower Factory Path (0)/Isles Enemy: Lower Factory Path (0)": 14042006, + "Isles Enemy: Lower Factory Path (1)/Isles Enemy: Lower Factory Path (1)": 14042007, + "Medals/Japes Donkey Half Medal": 14042329, + "Medals/Japes Diddy Half Medal": 14042330, + "Medals/Japes Lanky Half Medal": 14042331, + "Medals/Japes Tiny Half Medal": 14042332, + "Medals/Japes Chunky Half Medal": 14042333, + "Medals/Aztec Donkey Half Medal": 14042334, + "Medals/Aztec Diddy Half Medal": 14042335, + "Medals/Aztec Lanky Half Medal": 14042336, + "Medals/Aztec Tiny Half Medal": 14042337, + "Medals/Aztec Chunky Half Medal": 14042338, + "Medals/Factory Donkey Half Medal": 14042339, + "Medals/Factory Diddy Half Medal": 14042340, + "Medals/Factory Lanky Half Medal": 14042341, + "Medals/Factory Tiny Half Medal": 14042342, + "Medals/Factory Chunky Half Medal": 14042343, + "Medals/Galleon Donkey Half Medal": 14042344, + "Medals/Galleon Diddy Half Medal": 14042345, + "Medals/Galleon Lanky Half Medal": 14042346, + "Medals/Galleon Tiny Half Medal": 14042347, + "Medals/Galleon Chunky Half Medal": 14042348, + "Medals/Forest Donkey Half Medal": 14042349, + "Medals/Forest Diddy Half Medal": 14042350, + "Medals/Forest Lanky Half Medal": 14042351, + "Medals/Forest Tiny Half Medal": 14042352, + "Medals/Forest Chunky Half Medal": 14042353, + "Medals/Caves Donkey Half Medal": 14042354, + "Medals/Caves Diddy Half Medal": 14042355, + "Medals/Caves Lanky Half Medal": 14042356, + "Medals/Caves Tiny Half Medal": 14042357, + "Medals/Caves Chunky Half Medal": 14042358, + "Medals/Castle Donkey Half Medal": 14042359, + "Medals/Castle Diddy Half Medal": 14042360, + "Medals/Castle Lanky Half Medal": 14042361, + "Medals/Castle Tiny Half Medal": 14042362, + "Medals/Castle Chunky Half Medal": 14042363, } @@ -879,6 +950,7 @@ def dk64_map_to_tab_index(data: Any) -> int: "external_pack_key": "ut_pack_path", "map_page_maps": ["maps/maps.json"], "map_page_groups": [ + ("Overview", ["overview"]), ("DK Isles", ["isles", "training", "snidelobby", "japeslobby", "azteclobby", "factorylobby", "galleonlobby", "forestlobby", "caveslobby", "castlelobby", "helmlobby"]), ("Jungle Japes", ["japes", "japesunder", "japesmountain", "shellhive"]), ("Angry Aztec", ["aztec", "tinytemple", "llamatemple", "dk5dt", "diddy5dt", "lanky5dt", "tiny5dt", "chunky5dt"]), @@ -890,6 +962,7 @@ def dk64_map_to_tab_index(data: Any) -> int: ("Hideout Helm", ["helm"]), ], "map_page_locations": [ + "locations/overview.json", "locations/japes.json", "locations/aztec.json", "locations/factory.json", From 6f68dfcedaec602f78243f8061d2172d29289596 Mon Sep 17 00:00:00 2001 From: UmedMuzl Date: Sun, 8 Feb 2026 22:05:23 -0600 Subject: [PATCH 6/7] lint --- __init__.py | 48 ++++---- archipelago/FillSettings.py | 5 +- archipelago/Regions.py | 2 +- archipelago/Tracker.py | 106 ++++++++++++++---- randomizer/Lists/CustomLocations.py | 6 +- .../CustomLocationsMiscellaneous.MD | 6 +- 6 files changed, 118 insertions(+), 55 deletions(-) diff --git a/__init__.py b/__init__.py index 112843de6..0a420b5ed 100644 --- a/__init__.py +++ b/__init__.py @@ -890,17 +890,17 @@ def _restore_custom_location_names(self, custom_location_names: dict): """Restore custom location names from slot data for UT regeneration.""" from randomizer.Lists.Location import LocationListOriginal as VanillaLocationList from archipelago.Regions import BASE_ID - + if not custom_location_names: return - + print(f"[DK64 UT] Restoring {len(custom_location_names)} custom location names") - + # Build enum_to_index mapping enum_to_index = {location: index for index, location in enumerate(VanillaLocationList)} # Build reverse mapping: location_id -> location_enum index_to_enum = {index: location for location, index in enum_to_index.items()} - + restored_count = 0 sample_names = [] for loc_id_str, data in custom_location_names.items(): @@ -917,7 +917,7 @@ def _restore_custom_location_names(self, custom_location_names: dict): restored_count += 1 if restored_count <= 5: sample_names.append(f" {new_name}") - + print(f"[DK64 UT] Restored {restored_count} names, samples:") for name in sample_names: print(name) @@ -1159,7 +1159,7 @@ def generate_early(self): # Check if this is a UT regeneration - use generation_is_fake flag is_ut_regen = hasattr(self.multiworld, "generation_is_fake") print(f"[DK64] Is UT regen: {is_ut_regen}, has generation_is_fake: {hasattr(self.multiworld, 'generation_is_fake')}") - + # Store custom location flags do_crown_shuffle = self.spoiler.settings.crown_placement_rando do_patch_shuffle = self.spoiler.settings.random_patches @@ -1177,7 +1177,7 @@ def generate_early(self): self.spoiler.settings.crown_placement_rando = do_crown_shuffle self.spoiler.settings.random_patches = do_patch_shuffle self.spoiler.settings.random_crates = do_crate_shuffle - + if not is_ut_regen: # Normal generation - run custom location shuffles if do_crown_shuffle: @@ -1287,7 +1287,7 @@ def generate_early(self): self.spoiler.settings.shuffled_location_types.append(Types.ArchipelagoItem) Generate_Spoiler(self.spoiler) - + # For UT: Restore custom location names after Generate_Spoiler if hasattr(self.multiworld, "generation_is_fake") and hasattr(self.multiworld, "re_gen_passthrough"): if "Donkey Kong 64" in self.multiworld.re_gen_passthrough: @@ -1349,7 +1349,7 @@ def generate_early(self): if hasattr(self.multiworld, "re_gen_passthrough"): if "Donkey Kong 64" in self.multiworld.re_gen_passthrough: passthrough = self.multiworld.re_gen_passthrough["Donkey Kong 64"] - + # Restore enemy, minigame, shop, and portal data if passthrough["EnemyData"]: for location, data in passthrough["EnemyData"].items(): @@ -1374,13 +1374,13 @@ def generate_early(self): if passthrough.get("DKPortalLocations") and passthrough["DKPortalLocations"]: # Restore DK Portal locations self.spoiler.human_entry_doors = passthrough["DKPortalLocations"] - + # Update entry handler region exits to point to the restored DK Portal locations # This matches the behavior in DoorData.assignDKPortal() from randomizer.Enums.Levels import Levels from randomizer.Lists.DoorLocations import door_locations, LEVEL_ENTRY_HANDLER_REGIONS from randomizer.LogicClasses import TransitionFront - + level_name_to_enum = { "Jungle Japes": Levels.JungleJapes, "Angry Aztec": Levels.AngryAztec, @@ -1390,7 +1390,7 @@ def generate_early(self): "Crystal Caves": Levels.CrystalCaves, "Creepy Castle": Levels.CreepyCastle, } - + for level_name, door_name in self.spoiler.human_entry_doors.items(): if door_name != "Vanilla": level_enum = level_name_to_enum.get(level_name) @@ -1400,22 +1400,20 @@ def generate_early(self): if door_data.name == door_name: # Update the entry handler region's exit to point to this door's logic region placement_region = LEVEL_ENTRY_HANDLER_REGIONS[level_enum] - self.spoiler.RegionList[placement_region].exits[1] = TransitionFront( - door_data.logicregion, lambda _: True - ) + self.spoiler.RegionList[placement_region].exits[1] = TransitionFront(door_data.logicregion, lambda _: True) break - + # Restore entrance randomization connections for yamlless generation if passthrough.get("EntranceRando") and passthrough["EntranceRando"]: # Store entrance connections for later restoration # These will be applied in connect_entrances when we detect yamlless generation self.saved_entrance_connections = passthrough["EntranceRando"] - + # Restore starting region for yamlless generation if passthrough.get("StartingRegion") and passthrough["StartingRegion"]: from randomizer.Enums.Regions import Regions from randomizer.Enums.Maps import Maps - + starting_region_data = passthrough["StartingRegion"] # Reconstruct the starting_region dictionary self.spoiler.settings.starting_region = { @@ -1469,7 +1467,7 @@ def exclude_locations(location_names: typing.List[str]): # Exclude the locations using Archipelago's exclude_locations mechanism if excluded_locations: exclude_locations(excluded_locations) - + # AFTER all regions are created, restore custom location shuffles for UT # This must happen here (not in generate_early) to override default placements if hasattr(self.multiworld, "generation_is_fake") and hasattr(self.multiworld, "re_gen_passthrough"): @@ -2080,13 +2078,13 @@ def fill_slot_data(self) -> dict: print(f" has crown_locations: {hasattr(self.spoiler, 'crown_locations')}") print(f" has dirt_patch_placement: {hasattr(self.spoiler, 'dirt_patch_placement')}") print(f" has meloncrate_placement: {hasattr(self.spoiler, 'meloncrate_placement')}") - if hasattr(self.spoiler, 'crown_locations'): + if hasattr(self.spoiler, "crown_locations"): print(f" crown_locations length: {len(self.spoiler.crown_locations) if self.spoiler.crown_locations else 0}") - if hasattr(self.spoiler, 'dirt_patch_placement'): + if hasattr(self.spoiler, "dirt_patch_placement"): print(f" dirt_patch_placement length: {len(self.spoiler.dirt_patch_placement) if self.spoiler.dirt_patch_placement else 0}") - if hasattr(self.spoiler, 'meloncrate_placement'): + if hasattr(self.spoiler, "meloncrate_placement"): print(f" meloncrate_placement length: {len(self.spoiler.meloncrate_placement) if self.spoiler.meloncrate_placement else 0}") - + # If hints are enabled, wait for hint compilation to complete if hasattr(self, "options") and self.options.hint_style > 0: self.hint_compilation_complete.wait() @@ -2599,10 +2597,10 @@ def interpret_slot_data(self, slot_data: dict[str, any]) -> dict[str, any]: # Added starting region and DK portal locations starting_region = slot_data.get("StartingRegion", {}) dk_portal_locations = slot_data.get("DKPortalLocations", {}) - + # Custom location names for UT regeneration custom_location_names = slot_data.get("CustomLocationNames", {}) - + # Custom location shuffle data for UT regeneration crown_shuffle_data = slot_data.get("CrownShuffleData", None) patch_shuffle_data = slot_data.get("PatchShuffleData", None) diff --git a/archipelago/FillSettings.py b/archipelago/FillSettings.py index b43c8bd67..a94633670 100644 --- a/archipelago/FillSettings.py +++ b/archipelago/FillSettings.py @@ -975,11 +975,10 @@ def handle_fake_generation_settings(settings: Settings, multiworld) -> None: if passthrough.get("StartingRegion"): from randomizer.Enums.Regions import Regions from randomizer.Enums.Maps import Maps as DK64Maps - + starting_region_data = passthrough["StartingRegion"] # Ensure all fields exist and are not None - if all(key in starting_region_data and starting_region_data[key] is not None - for key in ["region", "map", "exit", "region_name", "exit_name"]): + if all(key in starting_region_data and starting_region_data[key] is not None for key in ["region", "map", "exit", "region_name", "exit_name"]): try: settings.starting_region = { "region": Regions[starting_region_data["region"]], diff --git a/archipelago/Regions.py b/archipelago/Regions.py index 313fc8839..e58ab8a0e 100644 --- a/archipelago/Regions.py +++ b/archipelago/Regions.py @@ -116,7 +116,7 @@ def create_regions(multiworld: MultiWorld, player: int, spoiler: Spoiler, option spoiler.LocationList[location].name: (BASE_ID + index) for index, location in enumerate(DK64RLocation.LocationListOriginal) if spoiler.LocationList[location].type != Types.EnemyPhoto } all_locations_dynamic.update({"Victory": 0x00}) # Temp for generating goal location - + # Debug: check for custom location names custom_names = [name for name in all_locations_dynamic.keys() if "Battle Arena" in name or "Melon Crate" in name or "Dirt:" in name] if custom_names and len(custom_names) > 0: diff --git a/archipelago/Tracker.py b/archipelago/Tracker.py index 369980230..faf56b25c 100644 --- a/archipelago/Tracker.py +++ b/archipelago/Tracker.py @@ -5,13 +5,13 @@ def dk64_map_to_tab_index(data: Any) -> int: """Map DK64 game map ID to flat sub-area index for UT navigation. - + Returns the flat index across ALL sub-areas in map_page_groups. """ # Handle empty or None data if data is None or data == "" or data == b"": return 0 - + # Convert to int if needed try: if isinstance(data, str): @@ -21,11 +21,14 @@ def dk64_map_to_tab_index(data: Any) -> int: map_id = int(data) if not isinstance(data, int) else data except (ValueError, TypeError): return 0 - + map_to_flat_index = { # DK Isles (indices 0-10) - 34: 0, 189: 0, 97: 0, # isles - 176: 1, 171: 1, # training + 34: 0, + 189: 0, + 97: 0, # isles + 176: 1, + 171: 1, # training 169: 2, # japeslobby 173: 3, # azteclobby 175: 4, # factorylobby @@ -35,15 +38,26 @@ def dk64_map_to_tab_index(data: Any) -> int: 193: 8, # castlelobby 170: 9, # helmlobby 195: 10, # snidelobby - 203: 0, 204: 0, 205: 0, 206: 0, 207: 0, 214: 0, # K. Rool phases -> isles + 203: 0, + 204: 0, + 205: 0, + 206: 0, + 207: 0, + 214: 0, # K. Rool phases -> isles 15: 10, # Snide's -> snidelobby # Jungle Japes (indices 11-14) - 7: 11, 12: 11, 13: 11, 37: 11, # japes main area (beehive, painting room, blast) + 7: 11, + 12: 11, + 13: 11, + 37: 11, # japes main area (beehive, painting room, blast) 33: 12, # japesunder - 4: 13, 6: 13, # japesmountain (includes minecarts) + 4: 13, + 6: 13, # japesmountain (includes minecarts) # shellhive (14) - no specific map ID, part of main japes # Angry Aztec (indices 15-22) - 38: 15, 14: 15, 41: 15, # aztec main area + 38: 15, + 14: 15, + 41: 15, # aztec main area 16: 16, # tinytemple 20: 17, # llamatemple 19: 18, # dk5dt @@ -52,31 +66,79 @@ def dk64_map_to_tab_index(data: Any) -> int: 22: 21, # tiny5dt 24: 22, # chunky5dt # Frantic Factory (index 23) - 26: 23, 27: 23, 29: 23, 36: 23, 110: 23, # factory + 26: 23, + 27: 23, + 29: 23, + 36: 23, + 110: 23, # factory # Gloomy Galleon (index 24) - 30: 24, 49: 24, 45: 24, 31: 24, 39: 24, 44: 24, 179: 24, # galleon - 51: 24, 46: 24, 43: 24, 47: 24, 54: 24, + 30: 24, + 49: 24, + 45: 24, + 31: 24, + 39: 24, + 44: 24, + 179: 24, # galleon + 51: 24, + 46: 24, + 43: 24, + 47: 24, + 54: 24, # Fungi Forest (indices 25-28) - 48: 25, 55: 25, 64: 25, 71: 25, 70: 25, 63: 25, 52: 25, # forest main - 56: 25, 57: 25, 58: 25, 188: 25, + 48: 25, + 55: 25, + 64: 25, + 71: 25, + 70: 25, + 63: 25, + 52: 25, # forest main + 56: 25, + 57: 25, + 58: 25, + 188: 25, 61: 26, # frontmill - 62: 27, 60: 27, # rearmill + 62: 27, + 60: 27, # rearmill 59: 28, # barn # Crystal Caves (index 29) - 72: 29, 82: 29, 98: 29, 86: 29, 100: 29, 85: 29, 84: 29, # caves - 95: 29, 89: 29, 91: 29, 92: 29, 200: 29, 94: 29, 93: 29, 90: 29, 186: 29, + 72: 29, + 82: 29, + 98: 29, + 86: 29, + 100: 29, + 85: 29, + 84: 29, # caves + 95: 29, + 89: 29, + 91: 29, + 92: 29, + 200: 29, + 94: 29, + 93: 29, + 90: 29, + 186: 29, # Creepy Castle (indices 30-36) - 87: 30, 164: 30, 114: 30, 105: 30, 168: 30, 167: 30, 166: 30, 187: 30, # castle exterior + 87: 30, + 164: 30, + 114: 30, + 105: 30, + 168: 30, + 167: 30, + 166: 30, + 187: 30, # castle exterior 151: 31, # dungeontunnel 163: 32, # dungeon - 183: 33, 108: 33, # crypthub - 112: 34, 106: 34, # crypt + 183: 33, + 108: 33, # crypthub + 112: 34, + 106: 34, # crypt 88: 35, # ballroom - 113: 36, 185: 36, # museum + 113: 36, + 185: 36, # museum # Hideout Helm (index 37) 17: 37, # helm } - + flat_index = map_to_flat_index.get(map_id, 0) return flat_index diff --git a/randomizer/Lists/CustomLocations.py b/randomizer/Lists/CustomLocations.py index ba32763ba..821976a93 100644 --- a/randomizer/Lists/CustomLocations.py +++ b/randomizer/Lists/CustomLocations.py @@ -1572,7 +1572,11 @@ class LocationTypes(IntEnum): z=2385, max_size=64, logic_region=Regions.LlamaTemple, - logic=lambda l: Events.AztecLlamaSpit in l.Events and l.HasGun(Kongs.any) and l.swim and l.scope and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or l.isdonkey or l.isdiddy or l.islanky or l.ischunky), + logic=lambda l: Events.AztecLlamaSpit in l.Events + and l.HasGun(Kongs.any) + and l.swim + and l.scope + and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or l.isdonkey or l.isdiddy or l.islanky or l.ischunky), group=4, banned_types=[LocationTypes.CrownPad, LocationTypes.DirtPatch, LocationTypes.Bananaport], ), diff --git a/wiki/article_markdown/custom_locations/CustomLocationsMiscellaneous.MD b/wiki/article_markdown/custom_locations/CustomLocationsMiscellaneous.MD index 3f6c3c00c..2f185e041 100644 --- a/wiki/article_markdown/custom_locations/CustomLocationsMiscellaneous.MD +++ b/wiki/article_markdown/custom_locations/CustomLocationsMiscellaneous.MD @@ -124,7 +124,7 @@ | Aztec Llama Temple | Llama Temple: Vanilla Far Warp 1 | | `self.logic = lambda _: True` | | Aztec Llama Temple | Llama Temple: Vanilla Lava Warp 2 | | `self.logic = lambda _: True` | | Aztec Llama Temple | Llama Temple: Vanilla Close Warp 2 | | `self.logic = lambda _: True` | -| Aztec Llama Temple | In the Water | CrownPad, DirtPatch, Bananaport | `Events.AztecLlamaSpit in l.Events and l.HasGun(Kongs.any) and l.swim and l.scope and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or (not l.istiny))` | +| Aztec Llama Temple | In the Water | CrownPad, DirtPatch, Bananaport | `Events.AztecLlamaSpit in l.Events and l.HasGun(Kongs.any) and l.swim and l.scope and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or l.isdonkey or l.isdiddy or l.islanky or l.ischunky)` | | Aztec Llama Temple | Llama Temple: DK Switch | | `self.logic = lambda _: True` | | Aztec Llama Temple | Llama Temple: Lava Room | | `self.logic = lambda _: True` | @@ -333,7 +333,7 @@ | Crystal Caves | On igloo Pillar | MelonCrate | `(l.jetpack and l.isdiddy) or (l.twirl and l.istiny and (not l.isKrushaAdjacent(Kongs.tiny)))` | | Crystal Caves | On top of the Igloo | CrownPad, MelonCrate | `self.logic = lambda _: True` | | Crystal Caves | Under tag barrel near igloo | MelonCrate | `self.logic = lambda _: True` | -| Crystal Caves | In front of Igloo | CrownPad, DirtPatch, Bananaport | `(l.HasGun(Kongs.any) and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or (not l.istiny))) or l.Slam` | +| Crystal Caves | In front of Igloo | CrownPad, DirtPatch, Bananaport | `(l.HasGun(Kongs.any) and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or l.isdonkey or l.isdiddy or l.islanky or l.ischunky)) or l.Slam` | | Crystal Caves | In the mini cave | | `self.logic = lambda _: True` | | Crystal Caves | Near ice wall to boulder | | `self.logic = lambda _: True` | | Crystal Caves | In Giant Boulder Room | | `self.logic = lambda _: True` | @@ -538,7 +538,7 @@ | Training Grounds | Training Grounds: Near Mountain | | `l.climbing and ((l.twirl and l.istiny) or (l.monkey_maneuvers and l.isdonkey and (not l.isKrushaAdjacent(Kongs.donkey))))` | | Training Grounds | Training Grounds: Rear Cave | | `self.logic = lambda _: True` | | Training Grounds | Training Grounds: Banana Hoard (back) | | `(l.can_use_vines or l.CanMoonkick()) and l.climbing` | -| Training Grounds | Training Grounds: Underwater | CrownPad, DirtPatch | `l.HasGun(Kongs.any) and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or (not l.istiny)) and l.swim and l.scope` | +| Training Grounds | Training Grounds: Underwater | CrownPad, DirtPatch | `l.HasGun(Kongs.any) and ((l.istiny and l.isKrushaAdjacent(Kongs.tiny)) or l.isdonkey or l.isdiddy or l.islanky or l.ischunky) and l.swim and l.scope` | | Training Grounds | Training Grounds: Near Pool | | `self.logic = lambda _: True` | | Treehouse | Treehouse: back | | `self.logic = lambda _: True` | | Banana Fairy Room | Banana Fairy Room: Right of Queen | | `self.logic = lambda _: True` | From b2feeb5c7fc72da50ab48266ae5db1abaf1fd3a7 Mon Sep 17 00:00:00 2001 From: UmedMuzl Date: Sun, 8 Feb 2026 22:05:43 -0600 Subject: [PATCH 7/7] Update requirement_data.js --- requirement_data.js | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/requirement_data.js b/requirement_data.js index d73e3236f..61ebdec14 100644 --- a/requirement_data.js +++ b/requirement_data.js @@ -70,11 +70,15 @@ const requirement_data = { new Requirement(10, [[Moves.Coconut, Moves.Strong]]), // 2 bunches in AngryAztecOasis new Requirement(30, [[Moves.Coconut, Moves.AztecTunnelDoor]]), // 1 balloon, 2 balloons in AngryAztecMain new Requirement(15, [ // 15 bananas in LlamaTemple + [Moves.Mini, Moves.AztecTunnelDoor], [Moves.Coconut, Moves.AztecTunnelDoor, Moves.AztecLlama], [Moves.Grape, Moves.AztecTunnelDoor, Moves.AztecLlama], [Moves.Feather, Moves.AztecTunnelDoor, Moves.AztecLlama], ]), new Requirement(20, [ // 4 bunches in AztecDonkeyQuicksandCave + [Moves.LevelSlam, Moves.Strong, Moves.Diddy, Moves.AztecTunnelDoor], + [Moves.LevelSlam, Moves.Strong, Moves.Tiny, Moves.AztecTunnelDoor], + [Moves.LevelSlam, Moves.Strong, Moves.Chunky, Moves.AztecTunnelDoor], [Moves.LevelSlam, Moves.Coconut, Moves.Strong, Moves.AztecTunnelDoor, Moves.AztecLlama], [Moves.LevelSlam, Moves.Strong, Moves.Grape, Moves.AztecTunnelDoor, Moves.AztecLlama], [Moves.LevelSlam, Moves.Strong, Moves.Feather, Moves.AztecTunnelDoor, Moves.AztecLlama], @@ -92,11 +96,7 @@ const requirement_data = { [Moves.ClimbingCheck, Moves.AztecTunnelDoor], [Moves.Rocket, Moves.AztecTunnelDoor], ]), - new Requirement(10, [ // 1 balloon in AztecDonkeyQuicksandCave - [Moves.LevelSlam, Moves.Coconut, Moves.Strong, Moves.Peanut, Moves.AztecTunnelDoor, Moves.AztecLlama, Moves.AztecW5Bonus], - [Moves.LevelSlam, Moves.Strong, Moves.Peanut, Moves.Grape, Moves.AztecTunnelDoor, Moves.AztecLlama, Moves.AztecW5Bonus], - [Moves.LevelSlam, Moves.Strong, Moves.Peanut, Moves.Feather, Moves.AztecTunnelDoor, Moves.AztecLlama, Moves.AztecW5Bonus], - ]), + new Requirement(10, [[Moves.LevelSlam, Moves.Strong, Moves.Peanut, Moves.AztecTunnelDoor, Moves.AztecW5Bonus]]), // 1 balloon in AztecDonkeyQuicksandCave ], "Lanky": [ new Requirement(5, [[Moves.Moveless]]), // 5 bananas in AngryAztecOasis @@ -104,38 +104,35 @@ const requirement_data = { new Requirement(25, [[Moves.ClimbingCheck, Moves.AztecTunnelDoor]]), // 5 bunches in AngryAztecMain new Requirement(14, [[Moves.Diving, Moves.Grape, Moves.TinyTempleIce]]), // 1 bunch, 9 bananas in TempleVultureRoom new Requirement(10, [[Moves.Grape, Moves.AztecTunnelDoor, Moves.Aztec5DT]]), // 1 balloon in LankyTemple - new Requirement(5, [[Moves.Vines, Moves.Grape, Moves.AztecTunnelDoor, Moves.AztecLlama]]), // 1 bunch in LlamaTempleMatching - new Requirement(20, [[Moves.Diving, Moves.Grape, Moves.AztecTunnelDoor, Moves.AztecLlama]]), // 2 balloons in LlamaTemple + new Requirement(20, [ // 2 balloons in LlamaTemple + [Moves.Diving, Moves.Grape, Moves.Mini, Moves.AztecTunnelDoor], + [Moves.Diving, Moves.Grape, Moves.AztecTunnelDoor, Moves.AztecLlama], + ]), new Requirement(11, [ // 1 bunch, 6 bananas in LlamaTemple + [Moves.Mini, Moves.AztecTunnelDoor], [Moves.Coconut, Moves.AztecTunnelDoor, Moves.AztecLlama], [Moves.Grape, Moves.AztecTunnelDoor, Moves.AztecLlama], [Moves.Feather, Moves.AztecTunnelDoor, Moves.AztecLlama], ]), + new Requirement(5, [ // 1 bunch in LlamaTempleMatching + [Moves.Vines, Moves.Grape, Moves.Mini, Moves.AztecTunnelDoor], + [Moves.Vines, Moves.Grape, Moves.IsDiddy, Moves.AztecTunnelDoor], + [Moves.Vines, Moves.Grape, Moves.IsTiny, Moves.AztecTunnelDoor], + [Moves.Vines, Moves.Grape, Moves.IsChunky, Moves.AztecTunnelDoor], + [Moves.Vines, Moves.Grape, Moves.AztecTunnelDoor, Moves.AztecLlama], + ]), ], "Tiny": [ - new Requirement(25, [[Moves.AztecTunnelDoor]]), // 1 bunch, 1 bunch, 10 bananas, 5 bananas in AngryAztecMain + new Requirement(28, [[Moves.AztecTunnelDoor]]), // 1 bunch, 1 bunch, 10 bananas, 5 bananas in AngryAztecMain; 3 bananas in LlamaTemple + new Requirement(10, [[Moves.Feather, Moves.AztecTunnelDoor]]), // 1 balloon in LlamaTemple + new Requirement(2, [[Moves.Mini, Moves.AztecTunnelDoor]]), // 2 bananas in LlamaTempleBack new Requirement(20, [[Moves.Diving, Moves.Feather, Moves.TinyTempleIce]]), // 2 balloons in TempleKONGRoom - new Requirement(10, [[Moves.Feather, Moves.AztecTunnelDoor, Moves.AztecLlama]]), // 1 balloon in LlamaTemple + new Requirement(10, [[Moves.LevelSlam, Moves.Mini, Moves.AztecTunnelDoor]]), // 2 bunches in LlamaTempleBack new Requirement(5, [[Moves.Diving, Moves.Feather, Moves.Mini, Moves.TinyTempleIce]]), // 5 bananas in TempleUnderwater new Requirement(25, [ // 5 bunches in AngryAztecMain [Moves.ClimbingCheck, Moves.AztecTunnelDoor], [Moves.Twirl, Moves.AztecTunnelDoor], ]), - new Requirement(3, [ // 3 bananas in LlamaTemple - [Moves.Coconut, Moves.AztecTunnelDoor, Moves.AztecLlama], - [Moves.Grape, Moves.AztecTunnelDoor, Moves.AztecLlama], - [Moves.Feather, Moves.AztecTunnelDoor, Moves.AztecLlama], - ]), - new Requirement(2, [ // 2 bananas in LlamaTempleBack - [Moves.Coconut, Moves.Mini, Moves.AztecTunnelDoor, Moves.AztecLlama], - [Moves.Grape, Moves.Mini, Moves.AztecTunnelDoor, Moves.AztecLlama], - [Moves.Feather, Moves.Mini, Moves.AztecTunnelDoor, Moves.AztecLlama], - ]), - new Requirement(10, [ // 2 bunches in LlamaTempleBack - [Moves.LevelSlam, Moves.Coconut, Moves.Mini, Moves.AztecTunnelDoor, Moves.AztecLlama], - [Moves.LevelSlam, Moves.Grape, Moves.Mini, Moves.AztecTunnelDoor, Moves.AztecLlama], - [Moves.LevelSlam, Moves.Feather, Moves.Mini, Moves.AztecTunnelDoor, Moves.AztecLlama], - ]), ], "Chunky": [ new Requirement(29, [[Moves.Pineapple]]), // 4 bananas, 5 bunches in TempleStart