diff --git a/README.md b/README.md index ffe9650358..dd5ad9ea7d 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ Currently, the following games are supported: * Satisfactory * EarthBound * Mega Man 3 +* Gauntlet Legends For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 357c4c5a35..febe083502 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -80,6 +80,9 @@ # Final Fantasy Mystic Quest /worlds/ffmq/ @Alchav @wildham0 +# Gauntlet Legends +/worlds/gl/ @jamesbrq + # Heretic /worlds/heretic/ @Daivuk @KScl diff --git a/inno_setup.iss b/inno_setup.iss index 50c400550b..2a31d80d55 100644 --- a/inno_setup.iss +++ b/inno_setup.iss @@ -206,11 +206,17 @@ Root: HKCR; Subkey: "{#MyAppName}ebpatch"; ValueData: "Archi Root: HKCR; Subkey: "{#MyAppName}ebpatch\DefaultIcon"; ValueData: "{app}\ArchipelagoSNIClient.exe,0"; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}ebpatch\shell\open\command"; ValueData: """{app}\ArchipelagoSNIClient.exe"" ""%1"""; ValueType: string; ValueName: ""; + Root: HKCR; Subkey: ".apmm3"; ValueData: "{#MyAppName}mm3patch"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}mm3patch"; ValueData: "Archipelago Mega Man 3 Patch"; Flags: uninsdeletekey; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}mm3patch\DefaultIcon"; ValueData: "{app}\ArchipelagoBizHawkClient.exe,0"; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}mm3patch\shell\open\command"; ValueData: """{app}\ArchipelagoBizHawkClient.exe"" ""%1"""; ValueType: string; ValueName: ""; +Root: HKCR; Subkey: ".apgl"; ValueData: "{#MyAppName}glpatch"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""; +Root: HKCR; Subkey: "{#MyAppName}glpatch"; ValueData: "Archipelago Gauntlet Legends Patch"; Flags: uninsdeletekey; ValueType: string; ValueName: ""; +Root: HKCR; Subkey: "{#MyAppName}glpatch\DefaultIcon"; ValueData: "{app}\ArchipelagoLauncher.exe,0"; ValueType: string; ValueName: ""; +Root: HKCR; Subkey: "{#MyAppName}glpatch\shell\open\command"; ValueData: """{app}\ArchipelagoLauncher.exe"" ""%1"""; ValueType: string; ValueName: ""; + Root: HKCR; Subkey: ".archipelago"; ValueData: "{#MyAppName}multidata"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}multidata"; ValueData: "Archipelago Server Data"; Flags: uninsdeletekey; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}multidata\DefaultIcon"; ValueData: "{app}\ArchipelagoServer.exe,0"; ValueType: string; ValueName: ""; diff --git a/worlds/gl/Data.py b/worlds/gl/Data.py new file mode 100644 index 0000000000..d0985e4484 --- /dev/null +++ b/worlds/gl/Data.py @@ -0,0 +1,459 @@ +from collections.abc import Mapping, Sequence +from types import MappingProxyType +from typing import Final + +from .Locations import LocationData, get_locations_by_tags + +# Item name to ram value conversion +item_ids: Final[Mapping[str, int]] = MappingProxyType({ + "Strength": 0x000002, + "Speed": 0x000003, + "Magic": 0x000004, + "Armour": 0x000005, + "Gold": 0x000006, + "Key": 0x000007, + "XP": 0x000009, + "Level": 0x00000A, + "Class": 0x00000B, + "Max": 0x00000D, + "Compass": 0x000270, + "Lightning Potion": 0x001008, + "Light Potion": 0x002008, + "Acid Potion": 0x003008, + "Fire Potion": 0x004008, + "Acid Breath": 0x800480, + "Lightning Breath": 0x8004F0, + "Fire Breath": 0x800460, + "Light Amulet": 0x400870, + "Acid Amulet": 0x400880, + "Lightning Amulet": 0x4008F0, + "Fire Amulet": 0x400860, + "Lightning Shield": 0x400CF0, + "Fire Shield": 0x400C60, + "Invisibility": 0x4000E0, + "Levitate": 0x400030, + "Speed Boots": 0x400173, + "3-Way Shot": 0x400020, + "5-Way Shot": 0x400160, + "Rapid Fire": 0x400050, + "Reflective Shot": 0x400840, + "Reflective Shield": 0x400C40, + "Super Shot": 0x8008B0, + "Timestop": 0x4000D0, + "Phoenix Familiar": 0x400110, + "Growth": 0x400120, + "Shrink": 0x400130, + "Thunder Hammer": 0x800940, + "Anti-Death Halo": 0x7000A0, + "Invulnerability": 0x7000C0, + "Health": 0x000001, + "Runestone": 0x008210, + "Mirror Shard": 0x008260, + "Ice Axe of Untar": 0x8201C0, + "Flame of Tarkana": 0x8201D0, + "Scimitar of Decapitation": 0x8201E0, + "Marker's Javelin": 0x8201F0, + "Soul Savior": 0x820200, + "Mountain": 0x00804A, + "Castle": 0x00801A, + "Hell": 0x00806A, + "Ice": 0x00807A, + "Town": 0x00808A, + "Temple": 0x00809A, + "Battlefield": 0x0080DA, + "Skorne": 0x0080EA, + "Secret": 0x0080FA, + "Obelisk": 0x00800C, + "Minotaur": 0x0001A1, + "Falconess": 0x0001A2, + "Jackal": 0x0001A3, + "Tigress": 0x0001A4, + "Sumner": 0x0001A5, + "Skorne's Mask": 0x840620, + "Skorne's Horns": 0x840630, + "Skorne's Right Gauntlet": 0x840A40, + "Skorne's Left Gauntlet": 0x840A50, + "Death": 0x0000F0, + "Crossbow Shooter": 0x0000F1, + "Bomb Thrower": 0x0000F2, + "Bomb Runner": 0x0000F3, + "Golem": 0x0000F4, +}) + +# Character names used for slot data +characters: Final[tuple[str, ...]] = ("Minotaur", "Falconess", "Tigress", "Jackal", "Sumner") + +# Base item charge count per pickup +# Some items are bitwise +base_count: Final[Mapping[str, int]] = MappingProxyType({ + "Key": 1, + "Lightning Potion": 1, + "Light Potion": 1, + "Acid Potion": 1, + "Fire Potion": 1, + "Acid Breath": 5, + "Lightning Breath": 5, + "Fire Breath": 5, + "Light Amulet": 30, + "Acid Amulet": 30, + "Lightning Amulet": 30, + "Fire Amulet": 30, + "Lightning Shield": 10, + "Fire Shield": 10, + "Invisibility": 30, + "Levitate": 30, + "Speed Boots": 30, + "3-Way Shot": 30, + "5-Way Shot": 30, + "Rapid Fire": 30, + "Reflective Shot": 30, + "Reflective Shield": 30, + "Super Shot": 3, + "Timestop": 15, + "Phoenix Familiar": 30, + "Growth": 30, + "Shrink": 30, + "Thunder Hammer": 3, + "Anti-Death Halo": 30, + "Invulnerability": 30, + "Fruit": 50, + "Meat": 100, + "Gold": 100, + "Runestone 1": 1, + "Runestone 2": 2, + "Runestone 3": 3, + "Runestone 4": 4, + "Runestone 5": 5, + "Runestone 6": 6, + "Runestone 7": 7, + "Runestone 8": 8, + "Runestone 9": 9, + "Runestone 10": 10, + "Runestone 11": 11, + "Runestone 12": 12, + "Runestone 13": 13, + "Dragon Mirror Shard": 1, + "Chimera Mirror Shard": 3, + "Plague Fiend Mirror Shard": 4, + "Yeti Mirror Shard": 2, + "Valley of Fire Obelisk": 1, + "Dagger Peak Obelisk": 2, + "Cliffs of Desolation Obelisk": 3, + "Poisoned Fields Obelisk": 4, + "Haunted Cemetery Obelisk": 5, + "Castle Courtyard Obelisk": 6, + "Dungeon of Torment Obelisk": 7, + "Ice Axe of Untar": 1, + "Flame of Tarkana": 1, + "Scimitar of Decapitation": 1, + "Marker's Javelin": 1, + "Soul Savior": 1, + "Minotaur": 1, + "Falconess": 1, + "Tigress": 1, + "Jackal": 1, + "Sumner": 1, + "Poison Fruit": -50, + "Skorne's Mask": 50, + "Skorne's Horns": 50, + "Skorne's Left Gauntlet": 100, + "Skorne's Right Gauntlet": 100, + "Portal to Dagger Peak": 1, + "Portal to Cliffs of Desolation": 2, + "Portal to Lost Cave": 3, + "Portal to Volcanic Caverns": 4, + "Portal to Dragon's Lair": 5, + "Portal to Dungeon of Torment": 1, + "Portal to Tower Armory": 2, + "Portal to Castle Treasury": 3, + "Portal to Chimera's Keep": 4, + "Portal to Haunted Cemetery": 1, + "Portal to Venomous Spire": 2, + "Portal to Toxic Air Ship": 3, + "Portal to Vat of the Plague Fiend": 4, + "Portal to Frozen Camp": 1, + "Portal to Crystal Mine": 2, + "Portal to Erupting Fissure": 3, + "Portal to Yeti's Cavern": 4, + "Portal to Fortified Towers": 1, + "Portal to Infernal Fortress": 2, + "Death": 1, + "Crossbow Shooter": 1, + "Bomb Thrower": 1, + "Bomb Runner": 1, + "Golem": 1 +}) + +# (zone_config << 4) + room_config -> location list +level_locations: Final[Mapping[int, Sequence[LocationData]]] = MappingProxyType({ + # Zone 0x00 - Castle + 0x00: get_locations_by_tags("castle_courtyard"), + 0x01: get_locations_by_tags("dungeon_of_torment"), + 0x02: get_locations_by_tags("tower_armory"), + 0x03: get_locations_by_tags("castle_treasury"), + 0x08: get_locations_by_tags("chimeras_keep"), + + # Zone 0x03 - Mountain + 0x30: get_locations_by_tags("valley_of_fire"), + 0x31: get_locations_by_tags("dagger_peak"), + 0x32: get_locations_by_tags("cliffs_of_desolation"), + 0x33: get_locations_by_tags("lost_cave"), + 0x34: get_locations_by_tags("volcanic_cavern"), + 0x38: get_locations_by_tags("dragons_lair"), + + # Zone 0x07 - Town + 0x70: get_locations_by_tags("poisoned_fields"), + 0x71: get_locations_by_tags("haunted_cemetery"), + 0x72: get_locations_by_tags("venomous_spire"), + 0x73: get_locations_by_tags("toxic_air_ship"), + 0x78: get_locations_by_tags("plague_fiend"), + + # Zone 0x05 - Underworld + 0x50: get_locations_by_tags("gates_of_the_underworld"), + + # Zone 0x06 - Ice + 0x60: get_locations_by_tags("arctic_docks"), + 0x61: get_locations_by_tags("frozen_camp"), + 0x62: get_locations_by_tags("crystal_mine"), + 0x63: get_locations_by_tags("erupting_fissure"), + 0x68: get_locations_by_tags("yeti"), + + # Zone 0x0D - Temple + 0xD0: get_locations_by_tags("desecrated_temple"), + 0xD8: get_locations_by_tags("altar_of_skorne"), + + # Zone 0x0C - Battlefield + 0xC0: get_locations_by_tags("battle_trenches"), + 0xC1: get_locations_by_tags("fortified_towers"), + 0xC2: get_locations_by_tags("infernal_fortress"), +}) + +# Compressed level size in ROM +level_size: Final[tuple[int, ...]] = ( + 0x9E0, + 0x5E0, + 0x740, + 0x8A0, + 0x90, + 0x3B0, + 0x5A0, + 0x890, + 0x670, + 0x7D0, + 0x90, + 0xCE0, + 0xA50, + 0xA30, + 0x8E0, + 0x20, + 0x760, + 0xE90, + 0xE40, + 0xE00, + 0xCD0, + 0x20, + 0x3F0, + 0x0, + 0xB00, + 0xA30, + 0xB30 +) + +# Level address in ROM +level_address: Final[tuple[int, ...]] = ( + 0xF939B0, + 0xF958B0, + 0xF945B0, + 0xF94EE0, + 0xF84CC0, + 0xF910B0, + 0xF915B0, + 0xF91D00, + 0xF92710, + 0xF92F40, + 0xF84B70, + 0xF84FA0, + 0xF85EB0, + 0xF86B60, + 0xF877C0, + 0xF880E0, + 0xF901C0, + 0xF884E0, + 0xF89370, + 0xF8A5F0, + 0xF8B760, + 0xF8C7C0, + 0xF90B50, + 0x0, + 0xF8D960, + 0xF8E6E0, + 0xF8F110 +) + +# Level header address in ROM +level_header: Final[tuple[int, ...]] = ( + 0xF9DD9C, + 0xF9E07C, + 0xF9DE54, + 0xF9DF0C, + 0xF9DFC4, + 0xF9E6E0, + 0xF9E798, + 0xF9E850, + 0xF9E908, + 0xF9E9C0, + 0xF9EA78, + 0xF9F004, + 0xF9F0BC, + 0xF9F174, + 0xF9F22C, + 0xF9F2E4, + 0xF9E1C0, + 0xF9E330, + 0xF9E3E4, + 0xF9E498, + 0xF9E54C, + 0xF9E600, + 0xF9DC2C, + 0x0, + 0xF9DA04, + 0xF9DABC, + 0xF9DB74 +) + +# Runestones required to access difficulties +# Used in Rules.py for access calculation +difficulty_lambda: Final[Mapping[int, Sequence[int]]] = MappingProxyType({ + 0x3: (0, 2, 3, 4), + 0x0: (0, 5, 6, 7), + 0x7: (0, 8, 9, 10), + 0x6: (0, 11, 12, 13), + 0xD: (0, 14, 15, 16), + 0xC: (0, 17, 18, 19), + 0x5: (0, 20, 21, 22) +}) + +# Runestones required to access difficulties +# Used in Rules.py for access calculation +difficulty_lambda_no_portal: Final[Mapping[int, Sequence[int]]] = MappingProxyType({ + 0x3: (0, 0, 1, 2), + 0x0: (0, 2, 3, 4), + 0x7: (0, 5, 6, 7), + 0x6: (0, 8, 9, 10), + 0xD: (0, 11, 12, 13), + 0xC: (0, 14, 15, 16), + 0x5: (0, 17, 18, 19) +}) + +# ID's for names said by announcer +sounds: Final[Mapping[int, int]] = MappingProxyType({ + 0: 0x9D, + 1: 0x9E, + 2: 0xA7, + 3: 0xA5, + 5: 0x9F, + 6: 0xA1, + 7: 0xA0, + 8: 0xA2, + 9: 0xA7 +}) + +# ID's for colors said by announcer +colors: Final[Mapping[int, int]] = MappingProxyType({ + 0: 0xA3, + 1: 0xA6, + 2: 0x9C, + 3: 0xA4 +}) + +obelisks: Final[tuple[str, ...]] = ( + "Valley of Fire Obelisk", + "Dagger Peak Obelisk", + "Cliffs of Desolation Obelisk", + "Poisoned Fields Obelisk", + "Haunted Cemetery Obelisk", + "Castle Courtyard Obelisk", + "Dungeon of Torment Obelisk" +) + +mirror_shards: Final[tuple[str, ...]] = ( + "Dragon Mirror Shard", + "Chimera Mirror Shard", + "Yeti Mirror Shard", + "Plague Fiend Mirror Shard" +) + +portals: Final[Mapping[str, str]] = MappingProxyType({ + "Portal to Dagger Peak": "Mountain", + "Portal to Cliffs of Desolation": "Mountain", + "Portal to Lost Cave": "Mountain", + "Portal to Volcanic Caverns": "Mountain", + "Portal to Dragon's Lair": "Mountain", + "Portal to Dungeon of Torment": "Castle", + "Portal to Tower Armory": "Castle", + "Portal to Castle Treasury": "Castle", + "Portal to Chimera's Keep": "Castle", + "Portal to Frozen Camp": "Ice", + "Portal to Crystal Mine": "Ice", + "Portal to Erupting Fissure": "Ice", + "Portal to Yeti's Cavern": "Ice", + "Portal to Haunted Cemetery": "Town", + "Portal to Venomous Spire": "Town", + "Portal to Toxic Air Ship": "Town", + "Portal to Vat of the Plague Fiend": "Town", + "Portal to Fortified Towers": "Battlefield", + "Portal to Infernal Fortress": "Battlefield" +}) + +excluded_portals: Final[Mapping[str, list[str]]] = MappingProxyType({ + "Castle" : ["Portal to Dungeon of Torment", "Portal to Tower Armory", "Portal to Castle Treasury", "Portal to Chimera's Keep"], + "Town" : ["Portal to Haunted Cemetery", "Portal to Venomous Spire", "Portal to Toxic Air Ship", "Portal to Vat of the Plague Fiend"], + "Ice" : ["Portal to Frozen Camp", "Portal to Crystal Mine", "Portal to Erupting Fissure", "Portal to Yeti's Cavern"], + "Battlefield" : ["Portal to Fortified Towers", "Portal to Infernal Fortress"] +}) + +excluded_levels: Final[Mapping[str, list[str]]] = MappingProxyType({ + "Mountain" : ["Valley of Fire", "Dagger Peak", "Cliffs of Desolation", "Lost Cave", "Volcanic Caverns", "Dragon's Lair"], + "Castle" : ["Castle Courtyard" ,"Dungeon of Torment", "Tower Armory", "Castle Treasury", "Chimera's Keep"], + "Ice" : ["Arctic Docks", "Frozen Camp", "Crystal Mine", "Erupting Fissure", "Yeti's Cavern"], + "Town" : ["Poisoned Fields", "Haunted Cemetery", "Venomous Spire", "Toxic Air Ship", "Vat of the Plague Fiend"], + "Battlefield" : ["Battle Trenches", "Fortified Towers", "Infernal Fortress"] +}) + +excluded_obelisks: Final[Mapping[str, list[str]]] = MappingProxyType({ + "Castle" : ["Valley of Fire Obelisk", "Dagger Peak Obelisk", "Cliffs of Desolation Obelisk"], + "Town" : ["Castle Courtyard Obelisk", "Dungeon of Torment Obelisk"], + "Ice" : ["Poisoned Fields Obelisk", "Haunted Cemetery Obelisk"], +}) + +# Map location names to offsets in decompressed boss.bin +boss_location_offsets: Final[Mapping[str, int]] = MappingProxyType({ + "Dragon's Lair - Dragon Mirror Shard": 0x9C08, + "Yeti's Cavern - Yeti Mirror Shard": 0x9C18, + "Chimera's Keep - Chimera Mirror Shard": 0x9C28, + "Vat of the Plague Fiend - Plague Fiend Mirror Shard": 0x9C38, + "Altar of Skorne - Skorne's Mask": 0x9C48, + "Altar of Skorne - Skorne's Horns": 0x9C58, + "Altar of Skorne - Skorne's Left Gauntlet": 0x9C68, + "Altar of Skorne - Skorne's Right Gauntlet": 0x9C78 +}) + +boss_regions: Final[tuple[str, ...]] = ( + "Dragon's Lair", + "Yeti's Cavern", + "Chimera's Keep", + "Vat of the Plague Fiend", + "Altar of Skorne", + "Gates of the Underworld", +) + + +# Item IDs for spawner traps (77780087-77780090) +spawner_trap_ids: Final[tuple[int, ...]] = (77780087, 77780088, 77780089, 77780090) + +player_compass_index: Final[Mapping[int, int]] = MappingProxyType({ + 1: 1, + 2: 0, + 3: 3, + 4: 2 +}) diff --git a/worlds/gl/GauntletLegendsClient.py b/worlds/gl/GauntletLegendsClient.py new file mode 100644 index 0000000000..0d2c66877f --- /dev/null +++ b/worlds/gl/GauntletLegendsClient.py @@ -0,0 +1,728 @@ +import asyncio +import Utils +import settings +import os +import re +import socket +import traceback +import subprocess +import Patch + +from typing import Optional +from BaseClasses import ItemClassification +from CommonClient import ClientCommandProcessor, CommonContext, get_base_parser, gui_enabled, logger, server_loop +from NetUtils import ClientStatus, NetworkItem + +from .Data import ( + base_count, + item_ids, + level_locations, + sounds, + colors, + portals, + spawner_trap_ids, + player_compass_index +) +from .Items import ItemData, items_by_id + +READ = "READ_CORE_RAM" +WRITE = "WRITE_CORE_RAM" +PLAYER_CLASS = 0xFD30F +PLAYER_COLOR = 0xFD30E +SOUND_ADDRESS = 0xAE740 +SOUND_START = 0xEEFC +PLAYER_KILL = 0xFD300 +PLAYER_MENU = 0x9D3C +BOSS_GOAL = 0x45D34 +BOSS_GOAL_BACKUP = 0x45D3C +LOCATIONS_BASE_ADDRESS = 0x64A68 +ZONE_ID = 0x6CA58 +LEVEL_ID = 0x6CA5C + +MOD_ITEM_ID = 0x3FC800 +MOD_QUANTITY = 0x3FC804 +MOD_PLAYER_ID = 0x3FC808 +MOD_OBELISK_QUANTITY = 0x3FC7E4 +MOD_BOSS_GOAL = 0x3FC7E5 +MOD_PLAYERS_LIST = 0x3FC7D0 +MOD_COMPASS_COUNT = 0x3FC7D4 + +GOAL_POLLS = 5 + + +class RetroSocket: + def __init__(self): + self.host = "localhost" + self.port = 55355 + self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.socket.setblocking(False) + + def send(self, message: str): + try: + self.socket.sendto(message.encode(), (self.host, self.port)) + except Exception as e: + raise Exception("An error occurred while sending a message.") + + async def read(self, message: str) -> Optional[bytes]: + self.send(message) + try: + response = await asyncio.wait_for(asyncio.get_event_loop().sock_recv(self.socket, 30000), 1.0) + data = response.decode().strip("\n").split(" ") + b = b"" + for s in data[2:]: + if "-1" in s: + raise Exception("Client tried to read from an invalid address or ROM is not open...") + b += bytes.fromhex(s) + return b + except asyncio.TimeoutError: + logger.error("Timeout while waiting for socket response...") + await asyncio.sleep(2) + return None + except ConnectionResetError: + logger.error("The connection was reset...") + await asyncio.sleep(2) + return None + except OSError as e: + logger.error(f"Socket error during read: {e}") + await asyncio.sleep(2) + return None + + async def status(self) -> str: + message = "GET_STATUS" + self.send(message) + try: + data = await asyncio.wait_for(asyncio.get_event_loop().sock_recv(self.socket, 4096), 1.0) + return data.decode() + except (asyncio.TimeoutError, ConnectionResetError, OSError): + pass + + +def message_format(arg: str, params: str) -> str: + return f"{arg} {params}" + + +def param_format(adr: int, arr: bytes) -> str: + return " ".join([hex(adr)] + [f"0x{byte:02X}" for byte in arr]) + + +class GauntletLegendsCommandProcessor(ClientCommandProcessor): + def __init__(self, ctx: CommonContext): + super().__init__(ctx) + + def _cmd_deathlink_toggle(self): + """Toggle Deathlink on or off""" + self.ctx.deathlink_enabled = not self.ctx.deathlink_enabled + self.ctx.update_death_link(self.ctx.deathlink_enabled) + logger.info(f"Deathlink {('Enabled.' if self.ctx.deathlink_enabled else 'Disabled.')}") + + +class GauntletLegendsContext(CommonContext): + command_processor = GauntletLegendsCommandProcessor + game = "Gauntlet Legends" + items_handling = 0b101 + + def __init__(self, server_address, password): + super().__init__(server_address, password) + self.useful: list[NetworkItem] = [] + self.deathlink_pending: bool = False + self.deathlink_enabled: bool = False + self.deathlink_triggered: bool = False + self.gl_sync_task = None + self.glslotdata = None + self.socket = RetroSocket() + self.rom_loaded: bool = False + self.locations_checked: list[int] = [] + self.retro_connected: bool = False + self.scouted: bool = False + self.obelisks: list[NetworkItem] = [] + self.item_locations: list[int] = [] + self.obelisk_locations: list[int] = [] + self.chest_locations: list[int] = [] + self.spawner_locations: list[int] = [] + self.item_address: int = 0 + self.chest_address: int = 0 + self.spawner_address: int = 0 + self.vanilla_spawner_count: int = 0 + self.zone: int = 0 + self.level: int = 0 + self.current_zone: int = -1 + self.current_level: int = -1 + self.level_id: int = 0 + self.location_scouts: list[NetworkItem] = [] + self.players: list[int] = [] + self.queued_traps: list[tuple[str, int, bool]] = [] + self.spawned_traps: int = 0 + self.item_ram_indices: dict[int, int] = {} + self.chest_ram_indices: dict[int, int] = {} + self.goal_streak: int = 0 + + def on_deathlink(self, data: dict): + super().on_deathlink(data) + self.deathlink_pending = True + + async def update_stage(self): + self.zone = await self._read_ram_int(ZONE_ID, 1) + self.level = await self._read_ram_int(LEVEL_ID, 1) + + async def check_goal(self) -> bool: + if self.glslotdata is None: + return False + if self.glslotdata["goal"] == 1: + goal = await self._read_ram_int(BOSS_GOAL, 4) + backup = await self._read_ram_int(BOSS_GOAL_BACKUP, 4) + return goal == 0xA or backup == 0xA + elif self.glslotdata["goal"] == 2: + goal = await self._read_ram_int(MOD_BOSS_GOAL, 1, True) + if goal >= self.glslotdata["boss_goal_count"]: + self.goal_streak += 1 + else: + self.goal_streak = 0 + return self.goal_streak >= GOAL_POLLS + + def _normalize_item_name(self, name: str) -> str: + if "Runestone" in name: + return "Runestone" + if "Fruit" in name or "Meat" in name: + return "Health" + if "Obelisk" in name: + return "Obelisk" + if "Mirror" in name: + return "Mirror Shard" + if portals.get(name, False): + return portals[name] + return name + + async def update_item(self, name: str, count: int, player: int = None, infinite_count: bool = False): + name = self._normalize_item_name(name) + await self._write_ram(MOD_ITEM_ID, + int.to_bytes((item_ids[name] if not infinite_count else item_ids[name] & 0xFFFF), 4, + "little")) + await self._write_ram(MOD_QUANTITY, int.to_bytes(count, 4, "little", signed=True)) + await self._write_ram(MOD_PLAYER_ID, int.to_bytes(player, 4, "little")) + + async def server_auth(self, password_requested: bool = False): + if password_requested and not self.password: + await super(GauntletLegendsContext, self).server_auth(password_requested) + await self.get_username() + await self.send_connect() + + def on_package(self, cmd: str, args: dict): + if cmd in {"Connected"}: + self.glslotdata = args["slot_data"] + self.deathlink_enabled = bool(self.glslotdata["death_link"]) + if self.deathlink_enabled: + Utils.async_start(self.update_death_link(self.deathlink_enabled)) + elif cmd == "LocationInfo": + self.location_scouts = args["locations"] + elif cmd == "RoomInfo": + self.seed_name = args["seed_name"] + + # Update inventory based on items received from server + # Also adds starting items based on a few yaml options + async def handle_items(self): + self.players = list(await self._read_ram(MOD_PLAYERS_LIST, 4)) + self.players = [player for player in self.players if player != 0] + if not self.players: + return + for player in self.players: + active = await self._read_ram_int(PLAYER_KILL + (0x1F0 * (player - 1)), 1) + if active != 0x4: + continue + compass = await self._read_ram_int(MOD_COMPASS_COUNT + (2 * player_compass_index[player]), 2) + if compass - 1 < len(self.items_received): + for index in range(compass - 1, len(self.items_received)): + active = await self._read_ram_int(PLAYER_KILL + (0x1F0 * (player - 1)), 1) + if active != 0x4: + break + item = self.items_received[index].item + if player != self.players[0] and item in spawner_trap_ids: + continue + item_name = items_by_id[item].item_name + if self.current_zone in (0x8, 0xE) and item in spawner_trap_ids: + if len([trap for trap in self.queued_traps if trap[1] == index]) < 1: + self.queued_traps.append((item_name, index, False)) + await self.give_item(item_name, player) + await self.update_item("Compass", 1, player) + + async def give_item(self, item_name: str, player: int): + await self.wait_for_mod_clear() + await asyncio.sleep(0.02) + await self.update_item(item_name, base_count[item_name], player) + await self.wait_for_mod_clear() + await asyncio.sleep(0.02) + + async def wait_for_mod_clear(self, poll_interval: float = 0.05): + while True: + mod_data = await self.socket.read(message_format(READ, f"0x{MOD_ITEM_ID:x} 12")) + if mod_data and all(byte == 0 for byte in mod_data): + return True + await asyncio.sleep(poll_interval) + + async def _read_ram(self, address: int, size: int) -> bytes: + return await self.socket.read(message_format(READ, f"0x{address:x} {size}")) + + async def _read_ram_int(self, address: int, size: int, signed: bool = False) -> int: + data = await self._read_ram(address, size) + return int.from_bytes(data, "little", signed=signed) if data else 0 + + async def _write_ram(self, address: int, data: bytes): + self.socket.send(message_format(WRITE, param_format(address, data))) + + async def dead(self) -> bool: + val = await self._read_ram_int(PLAYER_KILL + (0x1F0 * (self.players[0] - 1)), 1) + return (val & 0xF) == 0x8 + + async def dead_or_menu(self) -> bool: + val = await self._read_ram_int(PLAYER_KILL + (0x1F0 * (self.players[0] - 1)), 1) + return (val & 0xF) == 0x8 or (val & 0xF) == 0x1 + + async def get_seed_name(self) -> str: + seed_name = await self._read_ram(0x3FC7F0, 0x10) + return seed_name.decode("utf-8").strip() + + async def scout_locations(self, ctx: "GauntletLegendsContext") -> None: + try: + self.location_scouts = [] + self.obelisk_locations = [] + self.item_locations = [] + self.chest_locations = [] + self.spawner_locations = [] + self.useful = [] + self.obelisks = [] + self.vanilla_spawner_count = 0 + self.item_ram_indices = {} + self.chest_ram_indices = {} + + raw_locations = [location for location in level_locations.get(self.level_id, []) if + "Mirror" not in location.name and "Skorne" not in location.name] + scoutable_location_ids = [location.id for location in raw_locations if + location.id in ctx.checked_locations or location.id in self.missing_locations] + + # Scout locations if any exist + if raw_locations: + await ctx.send_msgs([{ + "cmd": "LocationScouts", + "locations": scoutable_location_ids, + "create_as_hint": 0, + }]) + while not self.location_scouts: + await asyncio.sleep(0.1) + + # Build lookup for scouted items by location + scouted_by_location = {item.location: item for item in self.location_scouts} + + item_slots: list[int] = [] + chest_slots: list[int] = [] + appended_items: list[int] = [] + + for loc in raw_locations: + is_obelisk_loc = "Obelisk" in loc.name + is_chest_loc = (not is_obelisk_loc) and ( + "Chest" in loc.name + or ("Barrel" in loc.name and "Barrel of Gold" not in loc.name) + ) + + scouted = scouted_by_location.get(loc.id) + + if not scouted: + if is_obelisk_loc: + pass + elif is_chest_loc: + chest_slots.append(loc.id) + else: + item_slots.append(loc.id) + continue + + item_id = scouted.item + item_player = scouted.player + item_data = items_by_id.get(item_id, ItemData()) + + if is_obelisk_loc: + if "Obelisk" in item_data.item_name and item_player == self.slot: + + pass + else: + + appended_items.append(loc.id) + continue + + if item_player == self.slot and item_id in spawner_trap_ids: + continue + + if item_player != self.slot: + + if is_chest_loc: + chest_slots.append(loc.id) + else: + item_slots.append(loc.id) + continue + + if "Obelisk" in item_data.item_name: + continue + + if (item_data.progression in (ItemClassification.useful, ItemClassification.progression) + and is_chest_loc): + appended_items.append(loc.id) + continue + + if is_chest_loc: + chest_slots.append(loc.id) + else: + item_slots.append(loc.id) + + final_item_order = item_slots + appended_items + + self.item_ram_indices = { + loc_id: idx for idx, loc_id in enumerate(final_item_order) + } + self.chest_ram_indices = { + loc_id: idx for idx, loc_id in enumerate(chest_slots) + } + + # Categorize scouted locations - mirror ROM's patch_items logic exactly + for loc in raw_locations: + scouted_item = scouted_by_location.get(loc.id) + if not scouted_item: + continue + + item_id = scouted_item.item + item_player = scouted_item.player + item_data = items_by_id.get(item_id, ItemData()) + is_chest = "Chest" in loc.name or ("Barrel" in loc.name and "Barrel of Gold" not in loc.name) + + # Check obelisk locations + if "Obelisk" in loc.name: + if "Obelisk" in item_data.item_name and item_player == self.slot: + self.obelisk_locations.append(loc.id) + self.obelisks.append(scouted_item) + else: + self.item_locations.append(loc.id) + continue + + # Check spawner (ROM: item[1] == player and item[0] in SPAWNER_TRAP_IDS) + if item_player == self.slot and item_id in spawner_trap_ids: + self.spawner_locations.append(loc.id) + continue + + # Check non-local player (ROM: item[1] != player) - stays as item/chest + if item_player != self.slot: + if is_chest: + self.chest_locations.append(loc.id) + else: + self.item_locations.append(loc.id) + continue + + # Check obelisk item at non-obelisk location (ROM: "Obelisk" in item_name) + if "Obelisk" in item_data.item_name: + self.obelisk_locations.append(loc.id) + self.obelisks.append(scouted_item) + continue + + # Check useful/progression chest -> item conversion + if item_data.progression in (ItemClassification.useful, ItemClassification.progression) and is_chest: + self.item_locations.append(loc.id) + self.useful.append(scouted_item) + continue + + # Regular item/chest + if is_chest: + self.chest_locations.append(loc.id) + else: + self.item_locations.append(loc.id) + + self.scouted = True + except Exception: + logger.error(traceback.format_exc()) + + async def location_loop(self) -> list[int]: + if self.current_zone == -1: + self.current_zone = self.zone + self.current_level = self.level + self.level_id = (self.current_zone << 4) + self.current_level + + zone_or_level_changed = self.zone != self.current_zone or self.level != self.current_level + if zone_or_level_changed: + if self.current_level & 0x8 == 0x8 and self.level_id != 0x58 and not await self.dead_or_menu(): + await self.check_locations([loc.id for loc in level_locations[self.level_id] + if "Mirror Shard" in loc.name or "Skorne" in loc.name]) + self.current_zone = self.zone + self.current_level = self.level + self.level_id = (self.current_zone << 4) + self.current_level + self.scouted = False + self.spawned_traps = 0 + self.goal_streak = 0 + await asyncio.sleep(2) + + if self.current_zone in (0x8, 0xE): + return [] + + if not self.scouted: + await self.scout_locations(self) + + active = await self._read_ram_int(PLAYER_KILL + (0x1F0 * (self.players[0] - 1)), 1) + if active != 0x4: + return [] + + if len(self.queued_traps) > 0 and self.spawned_traps == 0: + for i, trap in enumerate(self.queued_traps): + trap_name, index, given = trap + if not given: + self.spawned_traps += 1 + await self.give_item(trap_name, self.players[0]) + self.queued_traps[i] = (trap_name, index, True) + if self.spawned_traps >= 5: + break + + locations_address = await self._read_ram_int(LOCATIONS_BASE_ADDRESS, 4) & 0xFFFFFF + self.item_address = await self._read_ram_int(locations_address + 0x14, 4) + self.spawner_address = await self._read_ram_int(locations_address + 0x1C, 4) + self.chest_address = await self._read_ram_int(locations_address + 0x30, 4) + + # Read vanilla spawner count from level header (2 bytes at offset 0x28) + spawner_count_data = await self._read_ram(locations_address + 0x6, 2) + if spawner_count_data and not self.vanilla_spawner_count: + total_spawner_count = int.from_bytes(spawner_count_data, "little") + # Vanilla count is total minus the ones we added + self.vanilla_spawner_count = total_spawner_count - len(self.spawner_locations) + + if 0x7FFF0BAD in (self.item_address, self.chest_address, self.spawner_address): + return [] + + self.item_address &= 0xFFFFFF + self.spawner_address &= 0xFFFFFF + self.chest_address &= 0xFFFFFF + + acquired = [] + + max_item_idx = max((self.item_ram_indices[loc_id] for loc_id in self.item_locations), default=-1) + item_section = await self._read_ram(self.item_address, (max_item_idx + 1) * 0x18) if max_item_idx >= 0 else b"" + for loc_id in self.item_locations: + offset = self.item_ram_indices[loc_id] * 0x18 + active_byte, state = item_section[offset + 0x2], item_section[offset + 0x3] + if state < 0x7F and active_byte == 1 and state == 0: + acquired.append(loc_id) + + obelisk = await self._read_ram_int(MOD_OBELISK_QUANTITY, 1) + for j, loc_id in enumerate(self.obelisk_locations): + bit = base_count[items_by_id[self.obelisks[j].item].item_name] - 1 + if obelisk & (1 << bit): + acquired.append(loc_id) + + max_chest_idx = max((self.chest_ram_indices[loc_id] for loc_id in self.chest_locations), default=-1) + chest_section = await self._read_ram(self.chest_address, (max_chest_idx + 1) * 0x18) if max_chest_idx >= 0 else b"" + for loc_id in self.chest_locations: + offset = self.chest_ram_indices[loc_id] * 0x18 + active_byte, state = chest_section[offset + 0x2], chest_section[offset + 0x3] + if state < 0x7F and active_byte == 1 and state != 1: + acquired.append(loc_id) + + # Check spawner locations - these are added after vanilla spawners + # Read spawners starting after vanilla_spawner_count + if self.spawner_locations: + spawner_start = self.spawner_address + (self.vanilla_spawner_count * 0x1C) + spawner_section = await self._read_ram(spawner_start, len(self.spawner_locations) * 0x1C) + for i, loc_id in enumerate(self.spawner_locations): + offset = i * 0x1C + active_byte, hit = spawner_section[offset + 0x2], spawner_section[offset + 0x1A] + if active_byte == 1 and hit == 1: + acquired.append(loc_id) + + await self.update_stage() + if self.zone != self.current_zone or self.level != self.current_level: + return [] + return [loc_id for loc_id in acquired if loc_id not in self.checked_locations] + + async def die(self): + """Trigger deathlink death with character-specific death sound.""" + self.deathlink_triggered = True + for player in self.players: + char = await self._read_ram_int(PLAYER_CLASS + (0x1F0 * (player - 1)), 1) + color = await self._read_ram_int(PLAYER_COLOR + (0x1F0 * (player - 1)), 1) + + # Play death sound + sound_data = (int.to_bytes(colors[color], 4, "little") + + int.to_bytes(sounds[char], 4, "little") + + int.to_bytes(0xBB, 4, "little")) + await self._write_ram(SOUND_ADDRESS, sound_data) + await self._write_ram(SOUND_START, int.to_bytes(0xE00AE718, 4, "little")) + await asyncio.sleep(2) + + # Stop sound and kill player + await self._write_ram(SOUND_START, int.to_bytes(0x0, 4, "little")) + await self._write_ram(PLAYER_KILL + (0x1F0 * (player - 1)), int.to_bytes(0x7, 1, "little")) + + def make_gui(self): + ui = super().make_gui() + ui.base_title = "Archipelago Gauntlet Legends Client" + return ui + + +async def gl_sync_task(ctx: GauntletLegendsContext): + logger.info("Starting N64 connector...") + while not ctx.exit_event.is_set(): + try: + if not ctx.retro_connected: + logger.info("Attempting to connect to Retroarch...") + status = await ctx.socket.status() + ctx.retro_connected = True + ctx.rom_loaded = "CONTENTLESS" not in status + logger.info("Connected to Retroarch") + continue + + if not ctx.rom_loaded: + status = await ctx.socket.status() + if "CONTENTLESS" in status: + logger.info("No ROM loaded, waiting...") + await asyncio.sleep(3) + continue + logger.info("ROM Loaded") + ctx.rom_loaded = True + + if not ctx.auth: + await asyncio.sleep(1) + continue + + seed_name = await ctx.get_seed_name() + if seed_name != ctx.seed_name[0:16]: + logger.info(f"ROM seed does not match room seed ({seed_name} != {ctx.seed_name}), " + f"please load the correct ROM.") + await ctx.disconnect() + continue + + await ctx.update_stage() + if ctx.zone == 0x10: + continue + + await ctx.handle_items() + checking = await ctx.location_loop() + + menu = await ctx._read_ram_int(PLAYER_MENU, 4) + alive = False + if ctx.deathlink_pending and ctx.deathlink_enabled and menu == 1: + ctx.deathlink_pending = False + ctx.deathlink_triggered = True + await ctx.die() + elif len(ctx.players) > 0: + player_state = await ctx._read_ram_int(PLAYER_KILL + (0x1F0 * (ctx.players[0] - 1)), 1) + dead = (player_state & 0xF) == 0x8 + alive = (player_state & 0xF) == 0x4 + if dead and ctx.deathlink_enabled and not ctx.deathlink_triggered: + await ctx.send_death(f"{ctx.player_names[ctx.slot]} ran out of food.") + ctx.deathlink_triggered = True + + if alive: + ctx.deathlink_triggered = False + + if checking: + ctx.locations_checked += checking + await ctx.check_locations(checking) + + # Only trust the goal check when the player is alive + if alive: + goal = await ctx.check_goal() + if not ctx.finished_game and goal: + await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) + ctx.finished_game = True + else: + ctx.goal_streak = 0 + + except Exception as e: + logger.error(f"Error: {e}\n{traceback.format_exc()}") + ctx.socket = RetroSocket() + ctx.retro_connected = False + await asyncio.sleep(2) + + +_original_opt_content: dict[str, str | None] = {} + + +async def _patch_opt(): + """Create RetroArch core options override for CountPerOp=1.""" + retroarch_path = settings.get_settings().gl_options.retroarch_path + override_dir = os.path.join(retroarch_path, "config", "Mupen64Plus-Next") + os.makedirs(override_dir, exist_ok=True) + override_path = os.path.join(override_dir, "Mupen64Plus-Next.opt") + target_setting = 'mupen64plus-CountPerOp = "1"' + + if override_path not in _original_opt_content: + _original_opt_content[override_path] = open(override_path).read() if os.path.exists(override_path) else None + + content = _original_opt_content[override_path] or "" + if target_setting in content: + return + + if "mupen64plus-CountPerOp" in content: + content = re.sub(r'mupen64plus-CountPerOp\s*=\s*"[^"]*"', target_setting, content) + else: + content = content.rstrip("\n") + f"\n{target_setting}\n" if content else f"{target_setting}\n" + + with open(override_path, "w") as f: + f.write(content) + + +def _restore_opt_files(): + for path, original in _original_opt_content.items(): + try: + if original is None and os.path.exists(path): + os.remove(path) + elif original is not None: + with open(path, "w") as f: + f.write(original) + except Exception as e: + logger.error(f"Failed to restore {path}: {e}") + _original_opt_content.clear() + + +async def _launch_retroarch(rom_path: str): + retroarch_path = settings.get_settings().gl_options.retroarch_path + retroarch_exe = os.path.join(retroarch_path, "retroarch.exe") + core_path = os.path.join(retroarch_path, "cores", "mupen64plus_next_libretro.dll") + + if not os.path.exists(retroarch_exe): + logger.error(f"RetroArch not found at: {retroarch_exe}") + return + + if not os.path.exists(core_path): + logger.error(f"Mupen64Plus core not found at: {core_path}") + return + + subprocess.Popen([retroarch_exe, "-L", core_path, rom_path]) + logger.info(f"Launched RetroArch with ROM: {rom_path}") + + # Wait for RetroArch to start up + await asyncio.sleep(2) + + +async def _patch_and_launch_game(patch_file: str): + metadata, output_file = Patch.create_rom_file(patch_file) + await _patch_opt() + await _launch_retroarch(output_file) + + +def launch(*args): + async def main(args): + if args.patch_file: + await asyncio.create_task(_patch_and_launch_game(args.patch_file)) + ctx = GauntletLegendsContext(args.connect, args.password) + ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop") + if gui_enabled: + ctx.run_gui() + ctx.run_cli() + ctx.gl_sync_task = asyncio.create_task(gl_sync_task(ctx), name="Gauntlet Legends Sync Task") + + await ctx.exit_event.wait() + ctx.server_address = None + + await ctx.shutdown() + + _restore_opt_files() + + parser = get_base_parser() + parser.add_argument("patch_file", default="", type=str, nargs="?", help="Path to an APGL file") + args = parser.parse_args(args) + + import colorama + + colorama.just_fix_windows_console() + asyncio.run(main(args)) + colorama.deinit() diff --git a/worlds/gl/Items.py b/worlds/gl/Items.py new file mode 100644 index 0000000000..0bfa14e815 --- /dev/null +++ b/worlds/gl/Items.py @@ -0,0 +1,43 @@ +from collections.abc import Mapping +from types import MappingProxyType +from typing import Final + +from BaseClasses import Item, ItemClassification +from .Data import portals, obelisks, mirror_shards + + +class ItemData: + id: int + item_name: str + progression: ItemClassification + rom_id: int + frequency: int + + def __init__(self, id: int | None = 0, item_name: str = "", progression: int = 0, rom_id: str = "0x0", frequency: int = 1): + self.id = id + self.item_name = item_name + self.progression = ItemClassification(progression) + self.rom_id = int(rom_id, 16) + self.frequency = frequency + + + +class GLItem(Item): + game: str = "Gauntlet Legends" + +def import_items() -> tuple[ItemData, ...]: + import orjson + import pkgutil + + return tuple(ItemData(**item) for item in orjson.loads(pkgutil.get_data(__name__, "json/items.json").decode("utf-8"))) + +item_list: Final[tuple[ItemData, ...]] = import_items() +item_table: Final[Mapping[str, ItemData]] = MappingProxyType({item.item_name: item for item in item_list}) +items_by_id: Final[Mapping[int, ItemData]] = MappingProxyType({item.id: item for item in item_list}) + +gauntlet_item_name_groups = { + "Runestone": [f"Runestone {i}" for i in range(1, 14)], + "Portal": portals.keys(), + "Obelisk": obelisks, + "Mirror Shard": mirror_shards +} diff --git a/worlds/gl/Locations.py b/worlds/gl/Locations.py new file mode 100644 index 0000000000..900f452b1a --- /dev/null +++ b/worlds/gl/Locations.py @@ -0,0 +1,43 @@ +from typing import Final, List, Dict + +from BaseClasses import Location + + +class LocationData: + name: str = "" + id: int = 0 + difficulty: int = 0 + tags: Final[tuple[str, ...]] + + def __init__(self, name, id, difficulty, tags=None): + if tags is None: + tags = [] + self.name = name + self.id = id + self.difficulty = difficulty + self.tags = tags + + +class GLLocation(Location): + game: str = "Gauntlet Legends" + +def import_locations() -> List[LocationData]: + import orjson + import pkgutil + + return [LocationData(**loc) for loc in orjson.loads(pkgutil.get_data(__name__, "json/locations.json").decode("utf-8"))] + + +def get_locations_by_tags(tags: str | List[str]) -> List[LocationData]: + if isinstance(tags, str): + tags = [tags] + return [loc for loc in all_locations if any(tag in loc.tags for tag in tags)] + + +all_locations: List[LocationData] = import_locations() + +location_table: Dict[str, int] = {locData.name: locData.id for locData in all_locations} + +location_id_to_name: Dict[int, str] = {locData.id: locData.name for locData in all_locations if locData.id is not None} + +locationName_to_data: Dict[str, LocationData] = {locData.name: locData for locData in all_locations} diff --git a/worlds/gl/Options.py b/worlds/gl/Options.py new file mode 100644 index 0000000000..a9f36b54f5 --- /dev/null +++ b/worlds/gl/Options.py @@ -0,0 +1,247 @@ +from dataclasses import dataclass + +from Options import Choice, PerGameCommonOptions, StartInventoryPool, Toggle, Range, DefaultOnToggle, \ + OptionSet, DeathLink + + +class IncludedAreas(OptionSet): + """ + Select which areas will have their locations included in the randomization pool. + Each selected area's stages and checks will be accessible in your world. + Unselected areas will not be included in the location pool. + Mountain is always available and cannot be excluded. + """ + display_name = "Included Areas" + valid_keys = ["Castle", "Town", "Ice", "Battlefield"] + default = ["Castle", "Town", "Ice", "Battlefield"] + + +class ChestBarrels(Choice): + """ + Choose how you want Chests and Barrels to be randomized. + None: Neither Chests nor Barrels will be added as locations. + All Chests: Chests will be added as locations, Barrels will not. + All Barrels: Barrels will be added as locations, Chests will not. + All Both: Both Chests and Barrels will be added as locations. + """ + display_name = "Chests and Barrels" + option_none = 0 + option_all_chests = 1 + option_all_barrels = 2 + option_all_both = 3 + default = 3 + + +class Obelisks(DefaultOnToggle): + """ + Obelisks will be added to the random pool as items. + Activating all the obelisks in an area will unlock access to the next. + Disabling this will lock obelisks in their original locations. + """ + + display_name = "Obelisks" + + +class MirrorShards(DefaultOnToggle): + """ + Mirror Shards will be added to the random pool as items. + Collecting all four mirror shards will unlock access to the Desecrated Temple. + Disabling this will lock mirror shards in their original locations. + """ + + display_name = "Mirror Shards" + + +class Portals(DefaultOnToggle): + """ + Level portals will be added to the random pool as items. + Getting a portal item will unlock access to that level. + Levels will no longer unlock in succession when clearing the previous level. + """ + display_name = "Portals" + + +class Goal(Choice): + """ + Choose your objective required to goal. + Defeat Skorne: Collect all 13 stones to unlock and defeat Skorne in the Underworld. + Defeat X Bosses: Defeat X number of bosses to goal. + """ + + display_name = "Goal" + option_defeat_skorne = 1 + option_defeat_x_bosses = 2 + default = 1 + + +class BossGoalCount(Range): + """ + Choose how many bosses you must defeat to goal if 'Defeat X Bosses' is selected as your goal. + This includes both Temple and Underworld Skorne. + """ + + display_name = "Boss Goal Count" + range_start = 1 + range_end = 6 + default = 4 + + +class MaxDifficulty(Range): + """ + Select the difficulty value you want to be the maximum. + This will affect the amount of checks in each level as well as enemy strength and number of spawners. + """ + + display_name = "Max Difficulty Value" + range_start = 1 + range_end = 4 + default = 4 + + +class InstantMaxDifficulty(DefaultOnToggle): + """ + All stages will load with their max difficulty on the first run through. + By default, stages increase in difficulty by 1 at a set interval that changes per zone. + The starting level for each zone increases gradually as you would progress in vanilla. + """ + + display_name = "Instant Max Difficulty" + + +class PermaSpeed(Toggle): + """ + You will be given speed boots with a permanent duration. + """ + + display_name = "Permanent Speed Boots" + + +class InfiniteKeys(Toggle): + """ + You will be given more keys than you could ever use. + """ + + display_name = "Infinite Keys" + + +class IncludedTraps(OptionSet): + """ + Choose what traps will be put in the item pool. + Valid Keys: Death, Poison Fruit, Crossbow Shooter, Bomb Thrower, Bomb Runner, Golem + """ + + display_name = "Included Traps" + valid_keys = ["Death", "Poison Fruit", "Crossbow Shooter", "Bomb Thrower", "Bomb Runner", "Golem"] + default = ["Death", "Poison Fruit", "Crossbow Shooter", "Bomb Thrower", "Bomb Runner", "Golem"] + + +class TrapsFrequency(Range): + """ + Choose the frequency of traps added into the item pool + This range is a percentage of all items in the pool that will be traps. + """ + + display_name = "Trap Frequency" + range_start = 0 + range_end = 90 + default = 10 + + +class LocalFillerFrequency(Range): + """ + Choose the frequency of filler items that will be placed locally in your world. + This range is a percentage of how many filler items will be locally placed before generation occurs. + """ + + display_name = "Local Filler Frequency" + range_start = 0 + range_end = 90 + default = 50 + + +class UnlockCharacterOne(Choice): + """ + Unlock a secret character for Player 1 from the start. + None: No secret characters will be unlocked. + Chosen Character: The selected character will be available from a new save. + """ + + option_none = 0 + option_minotaur = 1 + option_falconess = 2 + option_jackal = 3 + option_tigress = 4 + option_sumner = 5 + default = 0 + + +class UnlockCharacterTwo(Choice): + """ + Unlock a secret character for Player 2 from the start. + None: No secret characters will be unlocked. + Chosen Character: The selected character will be available from a new save. + """ + + option_none = 0 + option_minotaur = 1 + option_falconess = 2 + option_jackal = 3 + option_tigress = 4 + option_sumner = 5 + default = 0 + + +class UnlockCharacterThree(Choice): + """ + Unlock a secret character for Player 3 from the start. + None: No secret characters will be unlocked. + Chosen Character: The selected character will be available from a new save. + """ + + option_none = 0 + option_minotaur = 1 + option_falconess = 2 + option_jackal = 3 + option_tigress = 4 + option_sumner = 5 + default = 0 + + +class UnlockCharacterFour(Choice): + """ + Unlock a secret character for Player 4 from the start. + None: No secret characters will be unlocked. + Chosen Character: The selected character will be available from a new save. + """ + + option_none = 0 + option_minotaur = 1 + option_falconess = 2 + option_jackal = 3 + option_tigress = 4 + option_sumner = 5 + default = 0 + + +@dataclass +class GLOptions(PerGameCommonOptions): + death_link: DeathLink + start_inventory_from_pool: StartInventoryPool + included_areas: IncludedAreas + chests_barrels: ChestBarrels + obelisks: Obelisks + mirror_shards: MirrorShards + portals: Portals + goal: Goal + boss_goal_count: BossGoalCount + max_difficulty: MaxDifficulty + instant_max: InstantMaxDifficulty + infinite_keys: InfiniteKeys + permanent_speed: PermaSpeed + included_traps: IncludedTraps + traps_frequency: TrapsFrequency + local_filler_frequency: LocalFillerFrequency + unlock_character_one: UnlockCharacterOne + unlock_character_two: UnlockCharacterTwo + unlock_character_three: UnlockCharacterThree + unlock_character_four: UnlockCharacterFour diff --git a/worlds/gl/Regions.py b/worlds/gl/Regions.py new file mode 100644 index 0000000000..37adec1168 --- /dev/null +++ b/worlds/gl/Regions.py @@ -0,0 +1,137 @@ +import typing +from typing import Optional, Callable + +from BaseClasses import Region +from .Data import excluded_levels + +from .Locations import GLLocation, LocationData, get_locations_by_tags + +if typing.TYPE_CHECKING: + from . import GauntletLegendsWorld + + +def create_regions(world: "GauntletLegendsWorld"): + world.multiworld.regions.append(Region("Menu", world.player, world.multiworld)) + + regions_dict = get_regions_dict() + for name, locations in regions_dict.items(): + if name not in [level for region, levels in excluded_levels.items() if region in world.excluded_regions for level in levels]: + create_region(world, name, locations) + else: + world.disabled_locations.update([loc.name for loc in locations if loc.name not in world.disabled_locations]) + +def get_regions_dict() -> dict[str, list[LocationData]]: + """ + Returns a dictionary mapping region names to their corresponding location data lists. + """ + return { + "Valley of Fire": get_locations_by_tags("valley_of_fire"), + "Dagger Peak": get_locations_by_tags("dagger_peak"), + "Cliffs of Desolation": get_locations_by_tags("cliffs_of_desolation"), + "Lost Cave": get_locations_by_tags("lost_cave"), + "Volcanic Caverns": get_locations_by_tags("volcanic_cavern"), + "Dragon's Lair": get_locations_by_tags("dragons_lair"), + "Castle Courtyard": get_locations_by_tags("castle_courtyard"), + "Dungeon of Torment": get_locations_by_tags("dungeon_of_torment"), + "Tower Armory": get_locations_by_tags("tower_armory"), + "Castle Treasury": get_locations_by_tags("castle_treasury"), + "Chimera's Keep": get_locations_by_tags("chimeras_keep"), + "Poisoned Fields": get_locations_by_tags("poisoned_fields"), + "Haunted Cemetery": get_locations_by_tags("haunted_cemetery"), + "Venomous Spire": get_locations_by_tags("venomous_spire"), + "Toxic Air Ship": get_locations_by_tags("toxic_air_ship"), + "Vat of the Plague Fiend": get_locations_by_tags("plague_fiend"), + "Arctic Docks": get_locations_by_tags("arctic_docks"), + "Frozen Camp": get_locations_by_tags("frozen_camp"), + "Crystal Mine": get_locations_by_tags("crystal_mine"), + "Erupting Fissure": get_locations_by_tags("erupting_fissure"), + "Yeti's Cavern": get_locations_by_tags("yeti"), + "Desecrated Temple": get_locations_by_tags("desecrated_temple"), + "Altar of Skorne": get_locations_by_tags("altar_of_skorne"), + "Battle Trenches": get_locations_by_tags("battle_trenches"), + "Fortified Towers": get_locations_by_tags("fortified_towers"), + "Infernal Fortress": get_locations_by_tags("infernal_fortress"), + "Gates of the Underworld": get_locations_by_tags("gates_of_the_underworld") + } + + +def connect_regions(world: "GauntletLegendsWorld"): + names: dict[str, int] = {} + + connect(world, names, "Menu", "Valley of Fire") + connect(world, names, "Menu", "Dagger Peak", _portal_helper("Portal to Dagger Peak", world)) + connect(world, names, "Menu", "Cliffs of Desolation", _portal_helper("Portal to Cliffs of Desolation", world)) + connect(world, names, "Menu", "Lost Cave", _portal_helper("Portal to Lost Cave", world)) + connect(world, names, "Menu", "Volcanic Caverns", _portal_helper("Portal to Volcanic Caverns", world)) + connect(world, names, "Menu", "Dragon's Lair", _portal_helper("Portal to Dragon's Lair", world)) + connect(world, names, "Menu", "Castle Courtyard", + lambda state: state.has("Valley of Fire Obelisk", world.player) + and state.has("Dagger Peak Obelisk", world.player) + and state.has("Cliffs of Desolation Obelisk", world.player) + ) + connect(world, names, "Castle Courtyard", "Dungeon of Torment", _portal_helper("Portal to Dungeon of Torment", world)) + connect(world, names, "Castle Courtyard", "Tower Armory", _portal_helper("Portal to Tower Armory", world)) + connect(world, names, "Castle Courtyard", "Castle Treasury", _portal_helper("Portal to Castle Treasury", world)) + connect(world, names, "Castle Courtyard", "Chimera's Keep", _portal_helper("Portal to Chimera's Keep", world)) + connect(world, names, "Menu", "Poisoned Fields", + lambda state: state.has("Castle Courtyard Obelisk", world.player) + and state.has("Dungeon of Torment Obelisk", world.player) + ) + connect(world, names, "Poisoned Fields", "Haunted Cemetery", _portal_helper("Portal to Haunted Cemetery", world)) + connect(world, names, "Poisoned Fields", "Venomous Spire", _portal_helper("Portal to Venomous Spire", world)) + connect(world, names, "Poisoned Fields", "Toxic Air Ship", _portal_helper("Portal to Toxic Air Ship", world)) + connect(world, names, "Toxic Air Ship", "Vat of the Plague Fiend", _portal_helper("Portal to Vat of the Plague Fiend", world)) + connect(world, names, "Menu", "Arctic Docks", + lambda state: state.has("Poisoned Fields Obelisk", world.player) + and state.has("Haunted Cemetery Obelisk", world.player) + ) + connect(world, names, "Arctic Docks", "Frozen Camp", _portal_helper("Portal to Frozen Camp", world)) + connect(world, names, "Arctic Docks", "Crystal Mine", _portal_helper("Portal to Crystal Mine", world)) + connect(world, names, "Arctic Docks", "Erupting Fissure", _portal_helper("Portal to Erupting Fissure", world)) + connect(world, names, "Erupting Fissure", "Yeti's Cavern", _portal_helper("Portal to Yeti's Cavern", world)) + connect(world, names, "Menu", "Desecrated Temple", + lambda state: state.has("Dragon Mirror Shard", world.player) + and state.has("Chimera Mirror Shard", world.player) + and state.has("Plague Fiend Mirror Shard", world.player) + and state.has("Yeti Mirror Shard", world.player) + ) + connect(world, names, "Desecrated Temple", "Altar of Skorne") + connect(world, names, "Desecrated Temple", "Battle Trenches") + connect(world, names, "Desecrated Temple", "Fortified Towers", _portal_helper("Portal to Fortified Towers", world)) + connect(world, names, "Desecrated Temple", "Infernal Fortress", _portal_helper("Portal to Infernal Fortress", world)) + connect(world, names, "Menu", "Gates of the Underworld", + lambda state: state.has("stones", world.player, 13) + ) + +def _portal_helper(item: str, world: "GauntletLegendsWorld") -> Callable | None: + if world.options.portals.value: + return lambda state: state.has(item, world.player) + return None + + +def create_region(world: "GauntletLegendsWorld", name: str, locations: list[LocationData]): + reg = Region(name, world.player, world.multiworld) + reg.add_locations({loc.name: loc.id for loc in locations if loc.name not in world.disabled_locations}, GLLocation) + world.multiworld.regions.append(reg) + + +def connect(world: "GauntletLegendsWorld", + used_names: dict[str, int], + source: str, + target: str, + rule: Optional[Callable] = None, +): + excluded_levels_ = [level for region, levels in excluded_levels.items() if region in world.excluded_regions for level in levels] + if source in excluded_levels_ or target in excluded_levels_: + return + source_region = world.multiworld.get_region(source, world.player) + target_region = world.multiworld.get_region(target, world.player) + + if target not in used_names: + used_names[target] = 1 + name = target + else: + used_names[target] += 1 + name = target + (" " * used_names[target]) + + source_region.connect(target_region, name, rule) diff --git a/worlds/gl/Rom.py b/worlds/gl/Rom.py new file mode 100644 index 0000000000..2c997e1c2a --- /dev/null +++ b/worlds/gl/Rom.py @@ -0,0 +1,613 @@ +import io +import json +import os +import pkgutil +import traceback +import typing +import zlib +from random import Random + +import bsdiff4 + +import Utils +from BaseClasses import Location, ItemClassification + +from worlds.Files import APPatchExtension, APProcedurePatch, APTokenMixin + +from .Data import level_address, level_header, level_locations, level_size, boss_location_offsets, spawner_trap_ids +from .Items import ItemData, items_by_id +from .Locations import locationName_to_data, GLLocation + +if typing.TYPE_CHECKING: + from . import GauntletLegendsWorld + +TABLE_START_OFFSET = 0x12E0 +EXPANDED_GAME_ROM_OFFSET = 0x1000000 # 16MB mark + + +def create_spawner_from_item(item_data: bytearray, spawner_rom_id: int, difficulty: int) -> bytearray: + spawner = bytearray(16) + spawner[0:6] = item_data[0:6] + spawner[6:8] = (0).to_bytes(2, "big") + spawner[8:12] = spawner_rom_id.to_bytes(4, "big") + spawner[12:14] = (0x0003).to_bytes(2, "big") + spawner[14] = difficulty + spawner[15] = 0x00 + return spawner + + +def create_spawner_from_chest(chest_data: bytearray, spawner_rom_id: int, difficulty: int) -> bytearray: + spawner = bytearray(16) + spawner[0:6] = chest_data[0:6] + spawner[6:8] = chest_data[6:8] + spawner[8:12] = spawner_rom_id.to_bytes(4, "big") + spawner[12:14] = (0x0003).to_bytes(2, "big") + spawner[14] = difficulty + spawner[15] = 0x00 + return spawner + + +def be32(b: bytes) -> int: + return int.from_bytes(b, "big") + + +def write_be32(buf: bytearray, off: int, val: int): + buf[off:off + 4] = (val & 0xFFFFFFFF).to_bytes(4, "big") + + +def ensure_len(buf: bytearray, size: int, fill: int = 0): + if len(buf) < size: + buf.extend(bytes([fill]) * (size - len(buf))) + + +def n64_crc(rom: bytes, cic: int = 6102) -> tuple[int, int]: + """Calculate N64 CRC checksums.""" + if cic in (6101, 6102): + seed = 0xF8CA4DDC + elif cic == 6103: + seed = 0xA3886759 + elif cic == 6105: + seed = 0xDF26F436 + elif cic == 6106: + seed = 0x1FEA617A + else: + raise ValueError("Unsupported CIC") + + t1 = t2 = t3 = t4 = t5 = t6 = seed + + for i in range(0x1000, 0x101000, 4): + d = int.from_bytes(rom[i:i + 4], "big") + + if (t6 + d) & 0xFFFFFFFF < t6: + t4 = (t4 + 1) & 0xFFFFFFFF + + t6 = (t6 + d) & 0xFFFFFFFF + t3 ^= d + + r = ((d << (d & 31)) | (d >> (32 - (d & 31)))) & 0xFFFFFFFF + t5 = (t5 + r) & 0xFFFFFFFF + + if t2 > d: + t2 ^= r + else: + t2 ^= t6 ^ d + + if cic == 6105: + extra = int.from_bytes(rom[0x0750 + (i & 0xFF):0x0754 + (i & 0xFF)], "big") + t1 = (t1 + (extra ^ d)) & 0xFFFFFFFF + else: + t1 = (t1 + (t5 ^ d)) & 0xFFFFFFFF + + if cic == 6103: + crc1 = (t6 ^ t4) & 0xFFFFFFFF + crc2 = (t5 ^ t3) & 0xFFFFFFFF + elif cic == 6106: + crc1 = ((t6 * t4) + t3) & 0xFFFFFFFF + crc2 = ((t5 * t2) + t1) & 0xFFFFFFFF + else: + crc1 = (t6 ^ t4 ^ t3) & 0xFFFFFFFF + crc2 = (t5 ^ t2 ^ t1) & 0xFFFFFFFF + + return crc1, crc2 + + +def get_base_rom_as_bytes() -> bytes: + """ + Read the base ROM file and verify its MD5 hash. + Raises an exception if the ROM doesn't match the expected hash. + """ + try: + from . import GauntletLegendsWorld + GauntletLegendsWorld.settings.rom_file.validate(GauntletLegendsWorld.settings.rom_file) + with open(GauntletLegendsWorld.settings.rom_file, "rb") as infile: + base_rom_bytes = bytes(infile.read()) + except Exception: + traceback.print_exc() + raise Exception('Failed to read ROM file. Check file path and permissions.') + return base_rom_bytes + + +def get_base_rom_path(file_name: str = "") -> str: + if not os.path.exists(file_name): + file_name = Utils.user_path(file_name) + return file_name + + +# Contains header info and raw data for level item positions and rotations. +class LevelData: + stream: io.BytesIO + header: bytearray + item_addr: int + spawner_addr: int + obj_addr: int + chest_addr: int + end_addr: int + end_addr2: int + end_addr3: int + portal_addr: int + items: list[bytearray] + spawners: list[bytearray] + objects: list[bytearray] + chests: list[bytearray] + end: bytes + items_replaced_by_obelisks: int = 0 + chests_replaced_by_obelisks: int = 0 + chests_replaced_by_items: int = 0 + obelisks_replaced_by_items: int = 0 + obelisks_kept: int = 0 + items_replaced_by_spawners: int = 0 + chests_replaced_by_spawners: int = 0 + + def __init__(self): + self.items = [] + self.spawners = [] + self.objects = [] + self.chests = [] + self.end = b"" + + +class GLPatchExtension(APPatchExtension): + game = "Gauntlet Legends" + + # Patched ROM requires updated CRC values. + @staticmethod + def finalize_crc(caller: APProcedurePatch, rom: bytes) -> bytes: + options = json.loads(caller.get_file("options.json").decode("utf-8")) + rom = bytearray(rom) + + SEED_ROM_OFFSET = 0xFFFFF0 + SEED_LEN = 16 + + seed = options["seed_name"].encode("utf-8")[:SEED_LEN] + rom[SEED_ROM_OFFSET:SEED_ROM_OFFSET + SEED_LEN] = seed.ljust(SEED_LEN, b"\x00") + + rom = bytearray(rom) + crc1, crc2 = n64_crc(rom, cic=6102) + rom[0x10:0x14] = crc1.to_bytes(4, "big") + rom[0x14:0x18] = crc2.to_bytes(4, "big") + return bytes(rom) + + + @staticmethod + def apply_bsdiff4(caller: APProcedurePatch, rom: bytes, patch: str) -> bytes: + return bsdiff4.patch(rom, pkgutil.get_data(__name__, f"data/basepatch.bsdiff4")) + + # Decompress all levels, place all items in the levels. + @staticmethod + def patch_items(caller: APProcedurePatch, rom: bytes): + stream = io.BytesIO(rom) + options = json.loads(caller.get_file("options.json").decode("UTF-8")) + local_random = Random(options["seed"]) + player = options["player"] + + for i in range(len(level_locations)): + level: dict[str, tuple] = json.loads(caller.get_file(f"level_{i}.json").decode("utf-8")) + level_address_ = level_address[i] + if level_address_ == 0: + continue + stream.seek(level_address_, 0) + stream, data = get_level_data(stream, level_size[i], i) + + items_seen = 0 + items_deleted = 0 + chests_deleted = 0 + chests_seen = 0 + + for location_name, item in level.items(): + is_chest = chest_barrel(location_name) + if is_chest: + chest_index = chests_seen - chests_deleted + chests_seen += 1 + else: + item_index = items_seen - items_deleted + items_seen += 1 + + if item[0] == 0: + continue + if "Mirror" in location_name: + continue + + item_data = items_by_id.get(item[0], ItemData()) + rom_id = item_data.rom_id + if rom_id == 0x0302: + rom_id = local_random.choices( + [0x0300, 0x0301, 0x0302, 0x0303, 0x0304], + weights=[10, 20, 40, 20, 10] + )[0] + + # Handle obelisk locations + if "Obelisk" in location_name: + if "Obelisk" not in item_data.item_name: + # Non-obelisk item at obelisk location - convert obelisk to item + try: + index = next(idx for idx in range(len(data.objects)) if data.objects[idx][8] == 0x26) + data.items.append( + bytearray(data.objects[index][0:6]) + + (rom_id.to_bytes(2) if item[1] == player else bytes([0x27, 0x1C])) + + bytes([0x0, 0x0, 0x0, 0x0]) + ) + del data.objects[index] + data.obelisks_replaced_by_items += 1 + except (StopIteration, Exception): + pass + else: + # Obelisk item at obelisk location + try: + index = next(idx for idx in range(len(data.objects)) if data.objects[idx][8] == 0x26) + if item[1] == player: + data.objects[index][15] = item[0] - 77780054 + data.obelisks_kept += 1 + else: + data.items.append( + bytearray(data.objects[index][0:6]) + + bytes([0x27, 0x1C, 0x0, 0x0, 0x0, 0x0]) + ) + del data.objects[index] + data.obelisks_replaced_by_items += 1 + except (StopIteration, Exception): + pass + continue + + # Handle spawner trap items (local player only) + if item[1] == player and item[0] in spawner_trap_ids: + difficulty = locationName_to_data[location_name].difficulty + spawner_rom_id = items_by_id[item[0]].rom_id + if is_chest: + data.spawners.append(create_spawner_from_chest(data.chests[chest_index], spawner_rom_id, difficulty)) + del data.chests[chest_index] + chests_deleted += 1 + data.chests_replaced_by_spawners += 1 + else: + data.spawners.append(create_spawner_from_item(data.items[item_index], spawner_rom_id, difficulty)) + del data.items[item_index] + items_deleted += 1 + data.items_replaced_by_spawners += 1 + continue + + # Handle non-local player items + if item[1] != player: + if is_chest: + data.chests[chest_index][12:14] = [0x27, 0x1C] + if "Chest" in location_name: + data.chests[chest_index][9] = 0x1 + else: + data.items[item_index][6:8] = [0x27, 0x1C] + continue + + # Handle local player items + if "Obelisk" in items_by_id[item[0]].item_name: + # Convert item/chest to obelisk + if is_chest: + slice_ = bytearray(data.chests[chest_index][0:6]) + del data.chests[chest_index] + chests_deleted += 1 + data.chests_replaced_by_obelisks += 1 + else: + slice_ = bytearray(data.items[item_index][0:6]) + del data.items[item_index] + items_deleted += 1 + data.items_replaced_by_obelisks += 1 + data.objects.append( + slice_ + bytearray([ + 0x0, 0x0, 0x26, 0x1, 0x0, + locationName_to_data[location_name].difficulty, + 0x0, 0x0, 0x0, item[0] - 77780054, + 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + ]) + ) + elif item_data.progression in (ItemClassification.useful, ItemClassification.progression) and is_chest: + # Convert chest to item for useful/progression items + chest = data.chests[chest_index] + data.items.append( + bytearray(chest[0:6]) + + rom_id.to_bytes(2) + + bytes([chest[11], 0x0, 0x0, 0x0]) + ) + del data.chests[chest_index] + chests_deleted += 1 + data.chests_replaced_by_items += 1 + else: + # Regular item placement + if is_chest: + data.chests[chest_index][12:14] = rom_id.to_bytes(2) + if "Chest" in location_name: + data.chests[chest_index][9] = 0x2 + else: + data.items[item_index][6:8] = item_data.rom_id.to_bytes(2) + + # Write level data + uncompressed = level_data_reformat(data) + compressed = zenc(uncompressed) + stream.seek(level_header[i] + 4, 0) + stream.write(len(compressed).to_bytes(4, byteorder="big")) + stream.write(len(uncompressed).to_bytes(4, byteorder="big")) + write_pos = 0xFA1000 + (0x1500 * i) + stream.write((write_pos - 0x636E0).to_bytes(4, byteorder="big")) + stream.seek(write_pos, 0) + stream.write(compressed) + + return stream.getvalue() + + @staticmethod + def patch_bins(caller: APProcedurePatch, rom: bytes) -> bytes: + boss_items_data = json.loads(caller.get_file("boss_items.json").decode("UTF-8")) + options = json.loads(caller.get_file("options.json").decode("UTF-8")) + local_random = Random(options["seed"]) + + boss_entry_offset = TABLE_START_OFFSET + (2 * 0x30) + + rom = bytearray(rom) + + boss_rom_offset = be32(rom[boss_entry_offset + 0x10:boss_entry_offset + 0x14]) + boss_comp_size = be32(rom[boss_entry_offset + 0x14:boss_entry_offset + 0x18]) + + boss_compressed = bytes(rom[boss_rom_offset:boss_rom_offset + boss_comp_size]) + boss_decompressed = bytearray(zdec(boss_compressed)) + + FILLER_ROM_ID = 0x271C + + for location_name, item_data in boss_items_data.items(): + if location_name not in boss_location_offsets: + continue + + item_code, item_player = item_data + if not item_code: + continue + + if item_player != options["player"]: + rom_id = FILLER_ROM_ID + else: + rom_id = items_by_id[item_code].rom_id + + if rom_id == 0x0302: + rom_id = local_random.choices([0x0300, 0x0301, 0x0302, 0x0303, 0x0304], weights=[10, 20, 40, 20, 10])[0] + + hi_byte = (rom_id >> 8) & 0xFF + lo_byte = rom_id & 0xFF + + offset = boss_location_offsets[location_name] + boss_decompressed[offset:offset + 2] = hi_byte.to_bytes(2, "big") + boss_decompressed[offset + 2:offset + 4] = lo_byte.to_bytes(2, "big") + + boss_recompressed = zenc(boss_decompressed) + new_boss_comp_size = len(boss_recompressed) + + if new_boss_comp_size > boss_comp_size: + new_boss_rom_offset = EXPANDED_GAME_ROM_OFFSET + 0x100000 + new_boss_end = new_boss_rom_offset + new_boss_comp_size + ensure_len(rom, new_boss_end, fill=0xFF) + rom[new_boss_rom_offset:new_boss_end] = boss_recompressed + write_be32(rom, boss_entry_offset + 0x10, new_boss_rom_offset) + write_be32(rom, boss_entry_offset + 0x14, new_boss_comp_size) + else: + rom[boss_rom_offset:boss_rom_offset + new_boss_comp_size] = boss_recompressed + write_be32(rom, boss_entry_offset + 0x14, new_boss_comp_size) + if new_boss_comp_size < boss_comp_size: + leftover_start = boss_rom_offset + new_boss_comp_size + leftover_end = boss_rom_offset + boss_comp_size + rom[leftover_start:leftover_end] = bytes(leftover_end - leftover_start) + + # Write portals option + rom[0xFFFFE0] = options["portals"] + rom[0xFFFFE1] = options["instant_max"] + rom[0xFFFFE2] = options["max"] + rom[0xFFFFE4] = options["keys"] + rom[0xFFFFE5] = options["speed"] + rom[0xFFFFE8:0xFFFFEC] = options["characters"] + return bytes(rom) + + +class GLProcedurePatch(APProcedurePatch, APTokenMixin): + game = "Gauntlet Legends" + hash = "9cb963e8b71f18568f78ec1af120362e" + patch_file_ending = ".apgl" + result_file_ending = ".z64" + + procedure = [ + ("apply_bsdiff4", ["basepatch.bsdiff4"]), + ("patch_bins", []), + ("patch_items", []), + ("finalize_crc", []) + ] + + @classmethod + def get_source_data(cls) -> bytes: + return get_base_rom_as_bytes() + + +# Write data on all placed items into json files. +# Also save options +def write_files(world: "GauntletLegendsWorld", patch: GLProcedurePatch) -> None: + options_dict = { + "seed": world.multiworld.seed, + "seed_name": world.multiworld.seed_name, + "player": world.player, + "portals": world.options.portals.value, + "instant_max": world.options.instant_max.value, + "max": world.options.max_difficulty.value, + "keys": world.options.infinite_keys.value, + "speed": world.options.permanent_speed.value, + "characters": [world.options.unlock_character_one.value, world.options.unlock_character_two.value, + world.options.unlock_character_three.value, world.options.unlock_character_four.value] + } + patch.write_file("options.json", json.dumps(options_dict).encode("UTF-8")) + + # Write level files + for i, level in enumerate(level_locations.values()): + locations: list[Location] = [] + for location in level: + if location.name in world.disabled_locations: + locations += [GLLocation(world.player, location.name, location.id)] + else: + locations += [world.get_location(location.name)] + patch.write_file(f"level_{i}.json", json.dumps(locations_to_dict(locations)).encode("UTF-8")) + + # Write boss items file + boss_location_names = [ + "Dragon's Lair - Dragon Mirror Shard", + "Yeti's Cavern - Yeti Mirror Shard", + "Chimera's Keep - Chimera Mirror Shard", + "Vat of the Plague Fiend - Plague Fiend Mirror Shard", + "Altar of Skorne - Skorne's Mask", + "Altar of Skorne - Skorne's Horns", + "Altar of Skorne - Skorne's Left Gauntlet", + "Altar of Skorne - Skorne's Right Gauntlet" + ] + + boss_locations: list[Location] = [] + for location_name in boss_location_names: + if location_name in world.disabled_locations: + # Get location ID from locationName_to_data + location_data = locationName_to_data.get(location_name) + if location_data: + boss_locations += [GLLocation(world.player, location_name, location_data.id)] + else: + boss_locations += [world.get_location(location_name)] + + patch.write_file("boss_items.json", json.dumps(locations_to_dict(boss_locations)).encode("UTF-8")) + + +def locations_to_dict(locations: list[Location]) -> dict[str, tuple]: + return {location.name: (location.item.code, location.item.player) if location.item is not None else (0, 0) for + location in locations} + + +def patch_docks(data: LevelData) -> LevelData: + data.stream.seek(0x19AC, 0) + data.stream.write(bytes([0x3, 0x20, 0x0, 0x18, 0x1, 0x7C])) + data.stream.seek(0x74, 0) + data.stream.write(bytes([0x3, 0x0, 0x0, 0x1A, 0x1, 0x8])) + return data + + +def patch_camp(data: LevelData) -> LevelData: + data.stream.seek(0x1B74, 0) + data.stream.write(bytes([0xFE, 0xE9, 0x0, 0x3B, 0xFF, 0xDC, 0x0, 0x10])) + data.stream.seek(0x1B64, 0) + data.stream.write(bytes([0xFE, 0x84, 0x0, 0x3D, 0xFF, 0xE0, 0xFF, 0xF0])) + return data + + +def patch_trenches(data: LevelData) -> LevelData: + data.stream.seek(0xD4, 0) + data.stream.write(bytes([0xFB, 0x68, 0x0, 0x82])) + return data + + +# Zlib decompression with wbits set to -15 +def zdec(data): + decomp = zlib.decompressobj(-zlib.MAX_WBITS) + output = bytearray() + for i in range(0, len(data), 256): + output.extend(decomp.decompress(data[i: i + 256])) + output.extend(decomp.flush()) + return output + + +# Zlib compression with compression set to max and wbits set to -15 +def zenc(data): + compress = zlib.compressobj(zlib.Z_BEST_COMPRESSION, zlib.DEFLATED, -zlib.MAX_WBITS) + output = bytearray() + for i in range(0, len(data), 256): + output.extend(compress.compress(data[i: i + 256])) + output.extend(compress.flush()) + return output + + +# Create a LevelData object from raw decompressed bytes of a level +def get_level_data(stream: io.BytesIO, size: int, level: int = 0) -> tuple[io.BytesIO, LevelData]: + data = LevelData() + data.stream = io.BytesIO(zdec(stream.read(size))) + if level == 17: + data = patch_docks(data) + if level == 18: + data = patch_camp(data) + if level == 24: + data = patch_trenches(data) + data.header = bytearray(data.stream.read(0x5C)) + data.stream.seek(0) + data.item_addr = int.from_bytes(data.stream.read(4), "big") + data.spawner_addr = int.from_bytes(data.stream.read(4), "big") + data.stream.seek(4, 1) + data.obj_addr = int.from_bytes(data.stream.read(4), "big") + data.end_addr = int.from_bytes(data.stream.read(4), "big") + data.portal_addr = int.from_bytes(data.stream.read(4), "big") + data.chest_addr = int.from_bytes(data.stream.read(4), "big") + data.end_addr2 = int.from_bytes(data.stream.read(4), "big") + data.end_addr3 = int.from_bytes(data.stream.read(4), "big") + data.stream.seek(data.item_addr) + for i in range(data.stream.tell(), data.spawner_addr, 12): + data.stream.seek(i) + data.items += [bytearray(data.stream.read(12))] + for i in range(data.stream.tell(), data.obj_addr, 16): + data.stream.seek(i) + data.spawners += [bytearray(data.stream.read(16))] + for i in range(data.stream.tell(), data.chest_addr, 24): + data.stream.seek(i) + data.objects += [bytearray(data.stream.read(24))] + for i in range(data.stream.tell(), data.end_addr, 16): + data.stream.seek(i) + data.chests += [bytearray(data.stream.read(16))] + data.end = data.stream.read() + return stream, data + + +# Format a LevelData object back into a bytes object +# Format is header, items, spawners, objects, barrels/chests, then traps. +def level_data_reformat(data: LevelData) -> bytes: + stream = io.BytesIO() + obelisk_offset = 24 * ( + data.items_replaced_by_obelisks + data.chests_replaced_by_obelisks - data.obelisks_replaced_by_items) + item_offset = 12 * ( + data.chests_replaced_by_items + data.obelisks_replaced_by_items - data.items_replaced_by_obelisks - data.items_replaced_by_spawners) + chest_offset = 16 * ( + data.chests_replaced_by_obelisks + data.chests_replaced_by_items + data.chests_replaced_by_spawners) + spawner_offset = 16 * (data.items_replaced_by_spawners + data.chests_replaced_by_spawners) + + stream.write(int.to_bytes(0x5C, 4, "big")) + stream.write(int.to_bytes(data.spawner_addr + item_offset, 4, "big")) + stream.write(int.to_bytes(data.spawner_addr + item_offset, 4, "big")) + stream.write(int.to_bytes(data.obj_addr + item_offset + spawner_offset, 4, "big")) + stream.write(int.to_bytes(data.end_addr + item_offset + spawner_offset + obelisk_offset - chest_offset, 4, "big")) + stream.write( + int.to_bytes(data.portal_addr + item_offset + spawner_offset + obelisk_offset - chest_offset, 4, "big")) + stream.write(int.to_bytes(data.chest_addr + item_offset + spawner_offset + obelisk_offset, 4, "big")) + stream.write(int.to_bytes(data.end_addr2 + item_offset + spawner_offset + obelisk_offset - chest_offset, 4, "big")) + stream.write(int.to_bytes(data.end_addr3 + item_offset + spawner_offset + obelisk_offset - chest_offset, 4, "big")) + # Counts are 2 bytes each, big-endian + stream.write(len(data.items).to_bytes(2, "big")) + stream.write(bytes([0x0, 0x0])) + stream.write(len(data.spawners).to_bytes(2, "big")) + stream.write(len(data.objects).to_bytes(2, "big")) + data.stream.seek(stream.tell()) + temp = bytearray(data.stream.read(48)) + temp[7] = len(data.chests) + stream.write(temp) + for item in data.items + data.spawners + data.objects + data.chests: + stream.write(bytes(item)) + stream.write(data.end) + return stream.getvalue() + + +def chest_barrel(name: str): + return "Chest" in name or ("Barrel" in name and "Barrel of Gold" not in name) diff --git a/worlds/gl/Rules.py b/worlds/gl/Rules.py new file mode 100644 index 0000000000..7c86dc7d30 --- /dev/null +++ b/worlds/gl/Rules.py @@ -0,0 +1,62 @@ +import typing + +from BaseClasses import CollectionRule +from worlds.generic.Rules import add_rule, forbid_item + +from .Data import difficulty_lambda, level_locations, obelisks, boss_regions, excluded_levels, spawner_trap_ids, \ + difficulty_lambda_no_portal +from .Items import items_by_id +from .Locations import get_locations_by_tags +from .Options import Goal + +if typing.TYPE_CHECKING: + from . import GauntletLegendsWorld + + +def set_rules(world: "GauntletLegendsWorld"): + for location in get_locations_by_tags("no_obelisks") + (get_locations_by_tags("obelisk") if world.options.obelisks else []): + for item in obelisks: + if location.name not in world.disabled_locations: + forbid_item(world.get_location(location.name), item, world.player) + + for location in get_locations_by_tags("no_spawner"): + for item in spawner_trap_ids: + if location.name not in world.disabled_locations: + forbid_item(world.get_location(location.name), items_by_id[item].item_name, world.player) + + if not world.options.instant_max: + for level_id, locations in level_locations.items(): + for location in locations: + if location.difficulty > 1: + if location.name not in world.disabled_locations: + if location.name not in world.disabled_locations: + level_id_ = level_id >> 4 + difficulty = location.difficulty - 1 + if world.options.portals: + expected_count = difficulty_lambda[level_id_][difficulty] - ( + len(world.excluded_regions) * 4) + else: + expected_count = difficulty_lambda_no_portal[level_id_][difficulty] - ( + len(world.excluded_regions) * 4) + expected_count = max(expected_count, 0) + add_rule( + world.get_location(location.name), + lambda state, expected_count_=expected_count: state.has("progression", world.player, + expected_count) + ) + + +def goal_conditions(world: "GauntletLegendsWorld") -> CollectionRule: + if world.options.goal == Goal.option_defeat_skorne: + return lambda state: state.can_reach("Gates of the Underworld", "Region", world.player) + + eligible_boss_regions = [ + boss for boss in boss_regions + if boss not in [ + level for region, levels in excluded_levels.items() + if region in world.excluded_regions for level in levels + ] + ] + needed_boss_count = world.options.boss_goal_count.value + + return lambda state: sum(state.can_reach_region(boss, world.player) for boss in eligible_boss_regions) >= needed_boss_count diff --git a/worlds/gl/__init__.py b/worlds/gl/__init__.py new file mode 100644 index 0000000000..951aac57e6 --- /dev/null +++ b/worlds/gl/__init__.py @@ -0,0 +1,346 @@ +import os + +import settings + +from BaseClasses import ItemClassification, Tutorial, Item, CollectionState +from Fill import fast_fill +from typing import ClassVar + +from worlds.AutoWorld import WebWorld, World + +from worlds.LauncherComponents import Component, SuffixIdentifier, Type, components, launch +from .Data import obelisks, mirror_shards, portals, excluded_portals, \ + excluded_obelisks, level_locations +from .Items import GLItem, item_table, item_list, gauntlet_item_name_groups +from .Locations import LocationData, all_locations, location_table, get_locations_by_tags, locationName_to_data +from .Options import GLOptions, IncludedAreas, IncludedTraps +from .Regions import connect_regions, create_regions +from .Rom import GLProcedurePatch, write_files +from .Rules import set_rules, goal_conditions + + +def launch_client(*args): + from .GauntletLegendsClient import launch as launch_glclient + launch(launch_glclient, name="GauntletLegendsClient", args=args) + + +components.append( + Component( + "Gauntlet Legends Client", + func=launch_client, + component_type=Type.CLIENT, + file_identifier=SuffixIdentifier(".apgl"), + ), +) + + +class GauntletLegendsWebWorld(WebWorld): + theme = "partyTime" + tutorials = [ + Tutorial( + tutorial_name="Setup Guide", + description="A guide to playing Gauntlet Legends", + language="English", + file_name="setup_en.md", + link="setup/en", + authors=["jamesbrq"], + ), + ] + + +class GLSettings(settings.Group): + class RetorarchPath(settings.UserFolderPath): + """The location of your Retroarch folder""" + description = "Retroarch Folder" + + class RomFile(settings.UserFilePath): + """File name of the GL US rom""" + copy_to = "Gauntlet Legends (U) [!].z64" + description = "Gauntlet Legends ROM File" + md5s = ["9cb963e8b71f18568f78ec1af120362e"] + + retroarch_path: RetorarchPath = RetorarchPath(None) + rom_file: RomFile = RomFile(RomFile.copy_to) + rom_start: bool = True + + +class GauntletLegendsWorld(World): + """ + Adventure through the 5 realms to collect 13 runestones + and defeat the evil skorne. Treasure, enemies, and death + awaits. + """ + + game = "Gauntlet Legends" + web = GauntletLegendsWebWorld() + options_dataclass = GLOptions + options: GLOptions + settings: ClassVar[GLSettings] + item_name_groups = gauntlet_item_name_groups + item_name_to_id = {name: data.id for name, data in item_table.items()} + location_name_to_id = {loc_data.name: loc_data.id for loc_data in all_locations} + excluded_regions: set + items: list[Item] + unlockable: set + + disabled_locations: set[str] + + def generate_early(self) -> None: + self.disabled_locations = set() + self.excluded_regions = set() + self.unlockable = set() + self.items = [] + + def create_regions(self) -> None: + if self.options.chests_barrels == "none": + self.disabled_locations.update([ + location.name + for location in all_locations + if "Chest" in location.name or ("Barrel" in location.name and "Barrel of Gold" not in location.name) + ]) + elif self.options.chests_barrels == "all_chests": + self.disabled_locations.update([ + location.name + for location in all_locations + if "Barrel" in location.name and "Barrel of Gold" not in location.name + ]) + elif self.options.chests_barrels == "all_barrels": + self.disabled_locations.update([location.name for location in all_locations if "Chest" in location.name]) + + self.disabled_locations.update([location.name for location in all_locations + if location.difficulty > self.options.max_difficulty]) + self.excluded_regions.update([region for region in IncludedAreas.valid_keys if region not in self.options.included_areas.value]) + self.options.boss_goal_count.value = min(self.options.boss_goal_count.value, + 6 - len([region for region in self.excluded_regions if region != "Battlefield"])) + + create_regions(self) + connect_regions(self) + if not self.options.infinite_keys: + self.lock_item("Valley of Fire - Key 1", "Key") + self.lock_item("Valley of Fire - Key 5", "Key") + + if not self.options.obelisks: + self.lock_item("Valley of Fire - Obelisk", "Valley of Fire Obelisk") + self.lock_item("Dagger Peak - Obelisk", "Dagger Peak Obelisk") + self.lock_item("Cliffs of Desolation - Obelisk", "Cliffs of Desolation Obelisk") + self.lock_item("Castle Courtyard - Obelisk", "Castle Courtyard Obelisk") + self.lock_item("Dungeon of Torment - Obelisk", "Dungeon of Torment Obelisk") + self.lock_item("Poisoned Fields - Obelisk", "Poisoned Fields Obelisk") + self.lock_item("Haunted Cemetery - Obelisk", "Haunted Cemetery Obelisk") + + if not self.options.mirror_shards: + self.lock_item("Dragon's Lair - Dragon Mirror Shard", "Dragon Mirror Shard") + self.lock_item("Chimera's Keep - Chimera Mirror Shard", "Chimera Mirror Shard") + self.lock_item("Vat of the Plague Fiend - Plague Fiend Mirror Shard", "Plague Fiend Mirror Shard") + self.lock_item("Yeti's Cavern - Yeti Mirror Shard", "Yeti Mirror Shard") + + def fill_slot_data(self) -> dict: + characters = [ + self.options.unlock_character_one.value, + self.options.unlock_character_two.value, + self.options.unlock_character_three.value, + self.options.unlock_character_four.value, + ] + chests_barrels = self.options.chests_barrels.value + return { + "chests": int(chests_barrels == 3 or chests_barrels == 1), + "barrels": int(chests_barrels == 3 or chests_barrels == 2), + "speed": self.options.permanent_speed.value, + "keys": self.options.infinite_keys.value, + "characters": characters, + "max": self.options.max_difficulty.value, + "instant_max": self.options.instant_max.value, + "death_link": self.options.death_link.value, + "portals": self.options.portals.value, + "included_areas": [area for area in IncludedAreas.valid_keys if area in self.options.included_areas.value], + "mirror_shards": self.options.mirror_shards.value, + "obelisks": self.options.obelisks.value, + "goal": self.options.goal.value, + "boss_goal_count": self.options.boss_goal_count.value, + } + + def create_items(self) -> None: + # First add in all progression and useful items + required_items = [] + precollected = [item for item in item_list if item.item_name in [item.name for item in self.multiworld.precollected_items[self.player]]] + skipped_items = set() + items_required_count = len(self.multiworld.get_unfilled_locations(self.player)) + if self.options.infinite_keys: + skipped_items.add("Key") + if self.options.permanent_speed: + skipped_items.add("Speed Boots") + skipped_items.update([item for item in IncludedTraps.valid_keys if item not in self.options.included_traps.value]) + if not self.options.obelisks: + skipped_items.update([obelisk for obelisk in obelisks if obelisk not in self.unlockable]) + if not self.options.mirror_shards: + skipped_items.update([shard for shard in mirror_shards if shard not in self.unlockable]) + if not self.options.portals: + skipped_items.update([item for item in portals.keys()]) + if len(self.excluded_regions) > 0: + for region in self.excluded_regions: + skipped_items.update(excluded_portals.get(region, [])) + skipped_items.update(excluded_obelisks.get(region, [])) + for item in [item_ for item_ in item_list + if (ItemClassification.progression in item_.progression + or ItemClassification.useful in item_.progression) + and item_.item_name not in precollected + and item_.item_name not in skipped_items]: + freq = item.frequency + required_items += [item.item_name for _ in range(freq)] + items_required_count -= freq + + self.multiworld.itempool += [self.create_item(item_name) for item_name in required_items] + + # Then, get a random amount of fillers until we have as many items as we have locations + filler_items = [] + for item in [item_ for item_ in item_list + if ItemClassification.progression not in item_.progression + and ItemClassification.useful not in item_.progression + and item_.item_name not in skipped_items]: + + freq = item.frequency + if item.item_name == "Anti-Death Halo" and "Death" not in skipped_items and self.options.traps_frequency.value >= 30: + freq *= 2 + + filler_items += [item.item_name for _ in range(freq)] + self.random.shuffle(filler_items) + + if len(self.options.included_traps.value) != 0: + traps_cap = items_required_count - len( + [location for location in self.multiworld.get_unfilled_locations(self.player) if + "no_spawner" in locationName_to_data[location.name].tags]) + traps_frequency = int(len(self.get_locations()) * (self.options.traps_frequency / 100)) // len(self.options.included_traps.value) + traps_frequency = min(traps_frequency, traps_cap // len(self.options.included_traps.value)) + for item in self.options.included_traps.value: + if items_required_count == 0: + break + self.multiworld.itempool += [self.create_item(item) for _ in range(min(traps_frequency, items_required_count))] + items_required_count = max(items_required_count - traps_frequency, 0) + + for i in range(items_required_count): + if i < int(items_required_count * (self.options.local_filler_frequency / 100)): + if self.multiworld.players > 1: + self.items.append(self.create_item(filler_items.pop())) + else: + self.multiworld.itempool.append(self.create_item(filler_items.pop())) + else: + self.multiworld.itempool.append(self.create_item(filler_items.pop())) + + + def set_rules(self) -> None: + set_rules(self) + self.multiworld.completion_condition[self.player] = goal_conditions(self) + + def pre_fill(self) -> None: + local_item_count = len(self.items) + unfilled_locations = self.multiworld.get_unfilled_locations(self.player) + unfilled_names = {loc.name for loc in unfilled_locations} + skipped = get_locations_by_tags("skipped_local") + no_obelisk_locs = get_locations_by_tags("no_obelisks") + + # Group available locations by level + level_locs = {} + for level_id, level in level_locations.items(): + if level_id & 0x8 == 0x8: + continue + available = [loc for loc in level if loc.name in unfilled_names and loc.name not in skipped] + if available: + level_locs[level_id] = sorted(available, key=lambda l: l.difficulty, reverse=True) + + all_available = [loc for locs in level_locs.values() for loc in locs] + + # Calculate target per level, ensuring we don't fill entire regions + target_per_level = (local_item_count // len(level_locs)) + 2 if level_locs else 0 + local_locations = [] + + for level_id, locs in level_locs.items(): + # Leave at least 1 location unfilled per region if possible + max_from_level = max(1, len(locs) - 1) if len(locs) > 1 else len(locs) + count = min(target_per_level, max_from_level) + + # Split into harder/easier halves + mid = len(locs) // 2 + harder, easier = locs[:mid], locs[mid:] + self.random.shuffle(harder) + self.random.shuffle(easier) + + # Take 60% from harder, 40% from easier + harder_count = int(count * 0.6) + easier_count = count - harder_count + local_locations.extend(self.get_location(l.name) for l in harder[:harder_count]) + local_locations.extend(self.get_location(l.name) for l in easier[:easier_count]) + + # If still need more, pull from levels with most remaining availability + if len(local_locations) < local_item_count: + used_names = {loc.name for loc in local_locations} + remaining = [] + for level_id, locs in level_locs.items(): + available = [l for l in locs if l.name not in used_names] + for loc in available: + remaining.append((loc, len(available))) + + remaining.sort(key=lambda x: x[1], reverse=True) + needed = local_item_count - len(local_locations) + local_locations.extend(self.get_location(loc.name) for loc, _ in remaining[:needed]) + + # Ensure obelisk accessibility + used_names = {loc.name for loc in local_locations} + remaining_unfilled = [loc.name for loc in all_available if loc.name not in used_names] + + if remaining_unfilled and all(name in no_obelisk_locs for name in remaining_unfilled): + chosen_no_obelisk = [loc for loc in local_locations if loc.name in no_obelisk_locs] + unchosen_obelisk_ok = [loc for loc in all_available + if loc.name not in used_names and loc.name not in no_obelisk_locs] + + swap_count = min(len(chosen_no_obelisk) // 2, len(unchosen_obelisk_ok)) + if swap_count > 0: + self.random.shuffle(chosen_no_obelisk) + self.random.shuffle(unchosen_obelisk_ok) + + for i in range(swap_count): + local_locations.remove(chosen_no_obelisk[i]) + local_locations.append(self.get_location(unchosen_obelisk_ok[i].name)) + + # Final shuffle and fill + local_locations = local_locations[:local_item_count] + self.random.shuffle(self.items) + self.random.shuffle(local_locations) + fast_fill(self.multiworld, self.items, local_locations) + + def create_item(self, name: str) -> GLItem: + item = item_table[name] + return GLItem(item.item_name, item.progression, item.id, self.player) + + def lock_item(self, location: str, item_name: str) -> None: + item = self.create_item(item_name) + if location in self.disabled_locations: + self.unlockable.update({item_name}) + return + self.get_location(location).place_locked_item(item) + + def collect(self, state: "CollectionState", item: "Item") -> bool: + change = super().collect(state, item) + if change and "Runestone" in item.name: + state.prog_items[item.player]["stones"] += 1 + if change and (ItemClassification.progression in item.classification): + state.prog_items[item.player]["progression"] += 1 + return change + + def remove(self, state: "CollectionState", item: "Item") -> bool: + change = super().remove(state, item) + if change and "Runestone" in item.name: + state.prog_items[item.player]["stones"] -= 1 + if change and (ItemClassification.progression in item.classification): + state.prog_items[item.player]["progression"] -= 1 + return change + + def get_filler_item_name(self) -> str: + return self.random.choice(list(filter(lambda item: item.progression == ItemClassification.filler, item_list))).item_name + + def generate_output(self, output_directory: str) -> None: + patch = GLProcedurePatch(player=self.player, player_name=self.player_name) + write_files(self, patch) + rom_path = os.path.join( + output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}{patch.patch_file_ending}", + ) + patch.write(rom_path) diff --git a/worlds/gl/archipelago.json b/worlds/gl/archipelago.json new file mode 100644 index 0000000000..abee7fd162 --- /dev/null +++ b/worlds/gl/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Gauntlet Legends", + "authors": [ "jamesbrq" ], + "minimum_ap_version": "0.6.6", + "world_version": "2.1.7" +} diff --git a/worlds/gl/data/basepatch.bsdiff4 b/worlds/gl/data/basepatch.bsdiff4 new file mode 100644 index 0000000000..de0caba0dd Binary files /dev/null and b/worlds/gl/data/basepatch.bsdiff4 differ diff --git a/worlds/gl/docs/en_Gauntlet Legends.md b/worlds/gl/docs/en_Gauntlet Legends.md new file mode 100644 index 0000000000..da8dd8c1f6 --- /dev/null +++ b/worlds/gl/docs/en_Gauntlet Legends.md @@ -0,0 +1,55 @@ +# Gauntlet Legends + +## Where is the options page? + +The [player options page for this game](../player-options) contains all the options you need to configure and +export a config file. + +## What does randomization do to this game? + +Items which the player would normally acquire throughout the game have been moved around. Logic remains, so the game is +always able to be completed, but because of the item shuffle, the player may need to access certain areas before they +would in the vanilla game. + +## What is the goal of Gauntlet Legends when randomized? + +Defeat Skorne in the Underworld. This requires gathering all 13 Runestones to gain access to the Underworld, and being strong enough to beat Skorne. + +Along the way, players will need to activate Obelisks to unlock new areas for them to explore. +They may also need to collect Mirror Shards, which will unlock a 5th area to explore as well as the Cathedral level. + +An alternate goal is to defeat a certain number of unique bosses at the end of each area, which can be configured in the options. + +## What items and locations can get shuffled? + +Locations in which items can be found: +- All in-stage items +- All Chests +- All Barrels +- All Runestones +- All Obelisks +- All Mirror Shards + +Items that can be placed into locations: +- Keys +- Potions +- All consumable items +- Runestones +- Obelisks +- Mirror Shards +- Level Portals +- Death +- Golems +- Goblin Shooters, Bomb Throwers, and Bomb Runners + +The randomizer also includes new portal items, which can be used as an alternate way to unlock new levels, +and add an extra layer of progression to the game. + +## What does another world's item look like in Gauntlet Legends? + +Items will show up as the Archipelago Logo, both as items and in chests or barrels. + +## When the player receives an item, what happens? + +Items will be placed directly into the players inventory. +If the player either leaves a stage midway or dies, the items they received mid-level will be given back to them in the lobby. diff --git a/worlds/gl/docs/setup_en.md b/worlds/gl/docs/setup_en.md new file mode 100644 index 0000000000..f8b420c7b1 --- /dev/null +++ b/worlds/gl/docs/setup_en.md @@ -0,0 +1,58 @@ +# Setup Guide for Gauntlet Legends in Archipelago + +## Required Software + +- Retroarch: [Standalone](https://www.retroarch.com/?page=platforms), [Steam](https://store.steampowered.com/app/1118310/RetroArch/) +- The built-in Gauntlet Legends Client, which can be installed [here](https://github.com/ArchipelagoMW/Archipelago/releases) +- A US copy of Gauntlet Legends for the N64 + +## Configuring Retroarch + +### Enabling Network Commands + +You must go to Settings -> User Interface and turn the Show Advanced Settings to On. +Then in Settings -> Network, you must also turn On Network Commands. +Leave the port as the default. + +### Selecting a Core + +When selecting a core, make sure to select Mupen64-plus-next core. + +## Configuring your YAML file + +### What is a YAML file and why do I need one? + +Your YAML file contains a set of configuration options which provide the generator with information about how it should +generate your game. Each player of a multiworld will provide their own YAML file. This setup allows each player to enjoy +an experience customized for their taste, and different players in the same multiworld can all have different options. + +### Where do I get a YAML file? + +You can customize your options by visiting the +[Gauntlet Legends Options Page](/games/Gauntlet%20Legends/player-options) + +## Joining a MultiWorld Game + +### Obtain your N64 patch file + +When you join a multiworld game, you will be asked to provide your YAML file to whoever is hosting. +The host generating does not need a copy of Gauntlet Legends to be able to generate with a Gauntlet Legends yaml. + +Once that is done, the host will provide you with either a link to download your data file, +or with a zip file containing everyone's data files. Your data file should have a `.apgl` extension. + + +Double-click on your `.apgl` file to start the ROM patch process. Once the process is finished, the client will be started automatically. + +### Connect to the Multiserver + +This game uses its own custom client, named Gauntlet Legends Client. +Retroarch is only emulator this client will accept. + +Once both the client and the emulator are started, you must connect them. Once your ROM is open in Retroarch, +as long as the client is open they will be connected to each other. + +To connect the client to the multiserver simply put `
:` on the textfield on top and press enter (if the +server uses password, type in the bottom textfield `/connect
: [password]`). + +The client will prompt you for your slot name, once you enter and submit it, you will be connected to the lobby. diff --git a/worlds/gl/json/items.json b/worlds/gl/json/items.json new file mode 100644 index 0000000000..003cd41026 --- /dev/null +++ b/worlds/gl/json/items.json @@ -0,0 +1,574 @@ +[ + { + "id": 77780000, + "item_name": "Key", + "progression": 0, + "rom_id": "0x0000", + "frequency": 700 + }, + { + "id": 77780001, + "item_name": "Lightning Potion", + "progression": 0, + "rom_id": "0x0101", + "frequency": 30 + }, + { + "id": 77780002, + "item_name": "Light Potion", + "progression": 0, + "rom_id": "0x0102", + "frequency": 30 + }, + { + "id": 77780003, + "item_name": "Acid Potion", + "progression": 0, + "rom_id": "0x0103", + "frequency": 30 + }, + { + "id": 77780004, + "item_name": "Fire Potion", + "progression": 0, + "rom_id": "0x0104", + "frequency": 30 + }, + { + "id": 77780005, + "item_name": "Acid Breath", + "progression": 0, + "rom_id": "0x0212", + "frequency": 20 + }, + { + "id": 77780006, + "item_name": "Lightning Breath", + "progression": 0, + "rom_id": "0x0211", + "frequency": 20 + }, + { + "id": 77780007, + "item_name": "Fire Breath", + "progression": 0, + "rom_id": "0x0210", + "frequency": 20 + }, + { + "id": 77780008, + "item_name": "Light Amulet", + "progression": 0, + "rom_id": "0x0209", + "frequency": 20 + }, + { + "id": 77780009, + "item_name": "Acid Amulet", + "progression": 0, + "rom_id": "0x020A", + "frequency": 20 + }, + { + "id": 77780010, + "item_name": "Lightning Amulet", + "progression": 0, + "rom_id": "0x0208", + "frequency": 20 + }, + { + "id": 77780011, + "item_name": "Fire Amulet", + "progression": 0, + "rom_id": "0x0207", + "frequency": 20 + }, + { + "id": 77780012, + "item_name": "Lightning Shield", + "progression": 0, + "rom_id": "0x0218", + "frequency": 15 + }, + { + "id": 77780013, + "item_name": "Fire Shield", + "progression": 0, + "rom_id": "0x0217", + "frequency": 15 + }, + { + "id": 77780014, + "item_name": "Invisibility", + "progression": 0, + "rom_id": "0x0205", + "frequency": 15 + }, + { + "id": 77780015, + "item_name": "Levitate", + "progression": 0, + "rom_id": "0x021C", + "frequency": 10 + }, + { + "id": 77780016, + "item_name": "Speed Boots", + "progression": 0, + "rom_id": "0x0200", + "frequency": 30 + }, + { + "id": 77780017, + "item_name": "3-Way Shot", + "progression": 0, + "rom_id": "0x0204", + "frequency": 15 + }, + { + "id": 77780018, + "item_name": "5-Way Shot", + "progression": 0, + "rom_id": "0x020E", + "frequency": 15 + }, + { + "id": 77780019, + "item_name": "Rapid Fire", + "progression": 0, + "rom_id": "0x021A", + "frequency": 15 + }, + { + "id": 77780020, + "item_name": "Reflective Shot", + "progression": 0, + "rom_id": "0x0202", + "frequency": 10 + }, + { + "id": 77780021, + "item_name": "Reflective Shield", + "progression": 0, + "rom_id": "0x0216", + "frequency": 10 + }, + { + "id": 77780022, + "item_name": "Super Shot", + "progression": 0, + "rom_id": "0x0203", + "frequency": 15 + }, + { + "id": 77780023, + "item_name": "Timestop", + "progression": 0, + "rom_id": "0x020C", + "frequency": 15 + }, + { + "id": 77780024, + "item_name": "Phoenix Familiar", + "progression": 0, + "rom_id": "0x0213", + "frequency": 20 + }, + { + "id": 77780025, + "item_name": "Growth", + "progression": 0, + "rom_id": "0x0214", + "frequency": 20 + }, + { + "id": 77780026, + "item_name": "Shrink", + "progression": 0, + "rom_id": "0x0215", + "frequency": 15 + }, + { + "id": 77780027, + "item_name": "Thunder Hammer", + "progression": 0, + "rom_id": "0x0219", + "frequency": 15 + }, + { + "id": 77780028, + "item_name": "Anti-Death Halo", + "progression": 0, + "rom_id": "0x020D", + "frequency": 15 + }, + { + "id": 77780029, + "item_name": "Invulnerability", + "progression": 0, + "rom_id": "0x0206", + "frequency": 15 + }, + { + "id": 77780030, + "item_name": "Fruit", + "progression": 0, + "rom_id": "0x0401", + "frequency": 200 + }, + { + "id": 77780031, + "item_name": "Meat", + "progression": 0, + "rom_id": "0x0403", + "frequency": 150 + }, + { + "id": 77780032, + "item_name": "Runestone 1", + "progression": 1, + "rom_id": "0x1501" + }, + { + "id": 77780033, + "item_name": "Runestone 2", + "progression": 1, + "rom_id": "0x1502" + }, + { + "id": 77780034, + "item_name": "Runestone 3", + "progression": 1, + "rom_id": "0x1503" + }, + { + "id": 77780035, + "item_name": "Runestone 4", + "progression": 1, + "rom_id": "0x1504" + }, + { + "id": 77780036, + "item_name": "Runestone 5", + "progression": 1, + "rom_id": "0x1505" + }, + { + "id": 77780037, + "item_name": "Runestone 6", + "progression": 1, + "rom_id": "0x1506" + }, + { + "id": 77780038, + "item_name": "Runestone 7", + "progression": 1, + "rom_id": "0x1507" + }, + { + "id": 77780039, + "item_name": "Runestone 8", + "progression": 1, + "rom_id": "0x1508" + }, + { + "id": 77780040, + "item_name": "Runestone 9", + "progression": 1, + "rom_id": "0x1509" + }, + { + "id": 77780041, + "item_name": "Runestone 10", + "progression": 1, + "rom_id": "0x150A" + }, + { + "id": 77780042, + "item_name": "Runestone 11", + "progression": 1, + "rom_id": "0x150B" + }, + { + "id": 77780043, + "item_name": "Runestone 12", + "progression": 1, + "rom_id": "0x150C" + }, + { + "id": 77780044, + "item_name": "Runestone 13", + "progression": 1, + "rom_id": "0x150D" + }, + { + "id": 77780045, + "item_name": "Dragon Mirror Shard", + "progression": 1, + "rom_id": "0x2B01" + }, + { + "id": 77780046, + "item_name": "Yeti Mirror Shard", + "progression": 1, + "rom_id": "0x2B02" + }, + { + "id": 77780047, + "item_name": "Chimera Mirror Shard", + "progression": 1, + "rom_id": "0x2B03" + }, + { + "id": 77780048, + "item_name": "Plague Fiend Mirror Shard", + "progression": 1, + "rom_id": "0x2B04" + }, + { + "id": 77780049, + "item_name": "Ice Axe of Untar", + "progression": 2, + "rom_id": "0x2901" + }, + { + "id": 77780050, + "item_name": "Flame of Tarkana", + "progression": 2, + "rom_id": "0x2902" + }, + { + "id": 77780051, + "item_name": "Scimitar of Decapitation", + "progression": 2, + "rom_id": "0x2903" + }, + { + "id": 77780052, + "item_name": "Marker's Javelin", + "progression": 2, + "rom_id": "0x2904" + }, + { + "id": 77780053, + "item_name": "Soul Savior", + "progression": 2, + "rom_id": "0x2905" + }, + { + "id": 77780054, + "item_name": "Gold", + "progression": 0, + "rom_id": "0x0302", + "frequency": 850 + }, + { + "id": 77780055, + "item_name": "Valley of Fire Obelisk", + "progression": 1 + }, + { + "id": 77780056, + "item_name": "Dagger Peak Obelisk", + "progression": 1 + }, + { + "id": 77780057, + "item_name": "Cliffs of Desolation Obelisk", + "progression": 1 + }, + { + "id": 77780058, + "item_name": "Poisoned Fields Obelisk", + "progression": 1 + }, + { + "id": 77780059, + "item_name": "Haunted Cemetery Obelisk", + "progression": 1 + }, + { + "id": 77780060, + "item_name": "Castle Courtyard Obelisk", + "progression": 1 + }, + { + "id": 77780061, + "item_name": "Dungeon of Torment Obelisk", + "progression": 1 + }, + { + "id": 77780062, + "item_name": "Death", + "progression": 4, + "rom_id": "0x2101" + }, + { + "id": 77780063, + "item_name": "Poison Fruit", + "progression": 4, + "rom_id": "0x0402" + }, + { + "id": 77780064, + "item_name": "Skorne's Mask", + "progression": 2, + "rom_id": "0x2A01" + }, + { + "id": 77780065, + "item_name": "Skorne's Horns", + "progression": 2, + "rom_id": "0x2A02" + }, + { + "id": 77780066, + "item_name": "Skorne's Right Gauntlet", + "progression": 2, + "rom_id": "0x2A03" + }, + { + "id": 77780067, + "item_name": "Skorne's Left Gauntlet", + "progression": 2, + "rom_id": "0x2A04" + }, + { + "id": 77780068, + "item_name": "Portal to Dagger Peak", + "progression": 1, + "rom_id": "0x2709" + }, + { + "id": 77780069, + "item_name": "Portal to Cliffs of Desolation", + "progression": 1, + "rom_id": "0x270A" + }, + { + "id": 77780070, + "item_name": "Portal to Lost Cave", + "progression": 1, + "rom_id": "0x270B" + }, + { + "id": 77780071, + "item_name": "Portal to Volcanic Caverns", + "progression": 1, + "rom_id": "0x270C" + }, + { + "id": 77780072, + "item_name": "Portal to Dragon's Lair", + "progression": 1, + "rom_id": "0x270D" + }, + { + "id": 77780073, + "item_name": "Portal to Dungeon of Torment", + "progression": 1, + "rom_id": "0x270E" + }, + { + "id": 77780074, + "item_name": "Portal to Tower Armory", + "progression": 1, + "rom_id": "0x270F" + }, + { + "id": 77780075, + "item_name": "Portal to Castle Treasury", + "progression": 1, + "rom_id": "0x2710" + }, + { + "id": 77780076, + "item_name": "Portal to Chimera's Keep", + "progression": 1, + "rom_id": "0x2711" + }, + { + "id": 77780077, + "item_name": "Portal to Haunted Cemetery", + "progression": 1, + "rom_id": "0x2712" + }, + { + "id": 77780078, + "item_name": "Portal to Venomous Spire", + "progression": 1, + "rom_id": "0x2713" + }, + { + "id": 77780079, + "item_name": "Portal to Toxic Air Ship", + "progression": 1, + "rom_id": "0x2714" + }, + { + "id": 77780080, + "item_name": "Portal to Vat of the Plague Fiend", + "progression": 1, + "rom_id": "0x2715" + }, + { + "id": 77780081, + "item_name": "Portal to Frozen Camp", + "progression": 1, + "rom_id": "0x2716" + }, + { + "id": 77780082, + "item_name": "Portal to Crystal Mine", + "progression": 1, + "rom_id": "0x2717" + }, + { + "id": 77780083, + "item_name": "Portal to Erupting Fissure", + "progression": 1, + "rom_id": "0x2718" + }, + { + "id": 77780084, + "item_name": "Portal to Yeti's Cavern", + "progression": 1, + "rom_id": "0x2719" + }, + { + "id": 77780085, + "item_name": "Portal to Fortified Towers", + "progression": 1, + "rom_id": "0x271A" + }, + { + "id": 77780086, + "item_name": "Portal to Infernal Fortress", + "progression": 1, + "rom_id": "0x271B" + }, + { + "id": 77780087, + "item_name": "Crossbow Shooter", + "progression": 4, + "rom_id": "0x05030411" + }, + { + "id": 77780088, + "item_name": "Bomb Thrower", + "progression": 4, + "rom_id": "0x05030511" + }, + { + "id": 77780089, + "item_name": "Bomb Runner", + "progression": 4, + "rom_id": "0x05030612" + }, + { + "id": 77780090, + "item_name": "Golem", + "progression": 4, + "rom_id": "0x05080113" + } +] \ No newline at end of file diff --git a/worlds/gl/json/locations.json b/worlds/gl/json/locations.json new file mode 100644 index 0000000000..0d72983d3f --- /dev/null +++ b/worlds/gl/json/locations.json @@ -0,0 +1,13745 @@ +[ + { + "name": "Valley of Fire - Scroll", + "id": 88870001, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Key 1", + "id": 88870002, + "difficulty": 1, + "tags": [ + "valley_of_fire", + "skipped_local" + ] + }, + { + "name": "Valley of Fire - Key 2", + "id": 88870003, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Key 3 (Dif. 3)", + "id": 88870004, + "difficulty": 3, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Key 4", + "id": 88870005, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Fire Amulet", + "id": 88870006, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Key 5", + "id": 88870007, + "difficulty": 1, + "tags": [ + "valley_of_fire", + "skipped_local" + ] + }, + { + "name": "Valley of Fire - Key 6 (Dif. 2)", + "id": 88870008, + "difficulty": 2, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Key 7", + "id": 88870009, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Fruit 1 (Dif. 2)", + "id": 88870010, + "difficulty": 2, + "tags": [ + "valley_of_fire", + "no_obelisks" + ] + }, + { + "name": "Valley of Fire - Key 8 (Dif. 3)", + "id": 88870011, + "difficulty": 3, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Key 9 (Dif. 2)", + "id": 88870012, + "difficulty": 2, + "tags": [ + "valley_of_fire", + "no_obelisks" + ] + }, + { + "name": "Valley of Fire - Fire Potion 1 (Dif. 3)", + "id": 88870013, + "difficulty": 3, + "tags": [ + "valley_of_fire", + "no_obelisks" + ] + }, + { + "name": "Valley of Fire - Thunder Hammer (Dif. 2)", + "id": 88870014, + "difficulty": 2, + "tags": [ + "valley_of_fire", + "no_obelisks" + ] + }, + { + "name": "Valley of Fire - Fire Potion 2 (Dif. 4)", + "id": 88870015, + "difficulty": 4, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Large Gold Pile (Dif. 3)", + "id": 88870016, + "difficulty": 3, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Small Gold Pile 1 (Dif. 4)", + "id": 88870017, + "difficulty": 4, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Meat Slab (Dif. 4)", + "id": 88870018, + "difficulty": 4, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Drumstick (Dif. 3)", + "id": 88870019, + "difficulty": 3, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Fruit 2 (Dif. 4)", + "id": 88870020, + "difficulty": 4, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Key 10", + "id": 88870021, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Small Gold Pile 2 (Dif. 2)", + "id": 88870022, + "difficulty": 2, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire - Obelisk", + "id": 88870611, + "difficulty": 1, + "tags": [ + "valley_of_fire", + "obelisk", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Valley of Fire Barrel - Nothing 1", + "id": 88873500, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Chest - Meat 1 (Dif. 2)", + "id": 88873501, + "difficulty": 2, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Chest - Potion 1", + "id": 88873502, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Chest - Potion 2 (Dif. 2)", + "id": 88873503, + "difficulty": 2, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Chest - Invisibility 1 (Dif. 3)", + "id": 88873504, + "difficulty": 3, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Chest - Gold 1", + "id": 88873505, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Chest - Random Chest 1 (Dif. 3)", + "id": 88873506, + "difficulty": 3, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Chest - Gold 2", + "id": 88873507, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Chest - Fruit 1", + "id": 88873508, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Barrel - Nothing 2", + "id": 88873509, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Barrel - Gold 1", + "id": 88873510, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Barrel - Fruit 1 (Dif. 3)", + "id": 88873511, + "difficulty": 3, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Chest - 3-Way Shot 1 (Dif. 4)", + "id": 88873512, + "difficulty": 4, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Barrel - Nothing 3", + "id": 88873513, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Barrel - Scroll 1", + "id": 88873514, + "difficulty": 1, + "tags": [ + "valley_of_fire", + "no_obelisks" + ] + }, + { + "name": "Valley of Fire Barrel - Nothing 4", + "id": 88873515, + "difficulty": 1, + "tags": [ + "valley_of_fire", + "no_obelisks" + ] + }, + { + "name": "Valley of Fire Barrel - Key 1 (Dif. 4)", + "id": 88873516, + "difficulty": 4, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Barrel - Speed Boots 1", + "id": 88873517, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Barrel - Fire Breath 1", + "id": 88873518, + "difficulty": 1, + "tags": [ + "valley_of_fire", + "no_obelisks" + ] + }, + { + "name": "Valley of Fire Barrel - Key 2", + "id": 88873519, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Valley of Fire Barrel - Potion 1", + "id": 88873520, + "difficulty": 1, + "tags": [ + "valley_of_fire" + ] + }, + { + "name": "Dagger Peak - Growth", + "id": 88870023, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Runestone", + "id": 88870024, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 1", + "id": 88870025, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Speed Boots (Dif. 2)", + "id": 88870026, + "difficulty": 2, + "tags": [ + "dagger_peak", + "no_obelisks" + ] + }, + { + "name": "Dagger Peak - Key 2", + "id": 88870027, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 3", + "id": 88870028, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 4 (Dif. 4)", + "id": 88870029, + "difficulty": 4, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 5 (Dif. 4)", + "id": 88870030, + "difficulty": 4, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 6 (Dif. 3)", + "id": 88870031, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Large Pile of Gold 1 (Dif. 2)", + "id": 88870032, + "difficulty": 2, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Large Pile of Gold 2 (Dif. 3)", + "id": 88870033, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Full Barrel of Gold 1 (Dif. 4)", + "id": 88870034, + "difficulty": 4, + "tags": [ + "dagger_peak", + "no_obelisks" + ] + }, + { + "name": "Dagger Peak - Small Pile of Gold 1 (Dif. 2)", + "id": 88870035, + "difficulty": 2, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Small Pile of Gold 2 (Dif. 3)", + "id": 88870036, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Small Pile of Gold 3", + "id": 88870037, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Fire Potion 1", + "id": 88870038, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Fruit", + "id": 88870039, + "difficulty": 1, + "tags": [ + "dagger_peak", + "no_obelisks" + ] + }, + { + "name": "Dagger Peak - Key 7 (Dif. 3)", + "id": 88870040, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 8 (Dif. 4)", + "id": 88870041, + "difficulty": 4, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Half Barrel of Gold 1 (Dif. 3)", + "id": 88870042, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 9 (Dif. 2)", + "id": 88870043, + "difficulty": 2, + "tags": [ + "dagger_peak", + "no_obelisks" + ] + }, + { + "name": "Dagger Peak - Fire Potion 2 (Dif. 3)", + "id": 88870044, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Poison Fruit (Dif. 3)", + "id": 88870045, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 10", + "id": 88870046, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 11 (Dif. 3)", + "id": 88870047, + "difficulty": 3, + "tags": [ + "dagger_peak", + "no_obelisks" + ] + }, + { + "name": "Dagger Peak - Key 12", + "id": 88870048, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 13", + "id": 88870049, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 14 (Dif. 2)", + "id": 88870050, + "difficulty": 2, + "tags": [ + "dagger_peak", + "no_obelisks" + ] + }, + { + "name": "Dagger Peak - Fire Potion 3 (Dif. 2)", + "id": 88870051, + "difficulty": 2, + "tags": [ + "dagger_peak", + "no_obelisks" + ] + }, + { + "name": "Dagger Peak - Meat 1 (Dif. 3)", + "id": 88870052, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 15", + "id": 88870053, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 16 (Dif. 2)", + "id": 88870054, + "difficulty": 2, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Key 17", + "id": 88870055, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak - Meat 2", + "id": 88870056, + "difficulty": 1, + "tags": [ + "dagger_peak", + "no_obelisks" + ] + }, + { + "name": "Dagger Peak - Key 18 (Dif. 4)", + "id": 88870057, + "difficulty": 4, + "tags": [ + "dagger_peak", + "no_obelisks" + ] + }, + { + "name": "Dagger Peak - Obelisk", + "id": 88870612, + "difficulty": 1, + "tags": [ + "dagger_peak", + "obelisk", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Dagger Peak Barrel - Rapid Fire 1", + "id": 88873600, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Key 1", + "id": 88873601, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Levitate 1", + "id": 88873602, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Fire Amulet 1 (Dif. 2)", + "id": 88873603, + "difficulty": 2, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Death 1", + "id": 88873604, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Fire Shield 1 (Dif. 2)", + "id": 88873605, + "difficulty": 2, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Scroll 1", + "id": 88873606, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Invulnerability 1 (Dif. 4)", + "id": 88873607, + "difficulty": 4, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Gold 1", + "id": 88873608, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Potion 1 (Dif. 4)", + "id": 88873609, + "difficulty": 4, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Gold 2", + "id": 88873610, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Fruit 1 (Dif. 4)", + "id": 88873611, + "difficulty": 4, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Fruit 2", + "id": 88873612, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Fruit 3 (Dif. 2)", + "id": 88873613, + "difficulty": 2, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Barrel - Poison Fruit 1", + "id": 88873614, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Scroll 1", + "id": 88873615, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Meat 1 (Dif. 2)", + "id": 88873616, + "difficulty": 2, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Gold 3 (Dif. 2)", + "id": 88873617, + "difficulty": 2, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - 3-Way Shot 1", + "id": 88873618, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Gold 4", + "id": 88873619, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Gold 5 (Dif. 3)", + "id": 88873620, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Random 1 (Dif. 2)", + "id": 88873621, + "difficulty": 2, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Gold 6 (Dif. 4)", + "id": 88873622, + "difficulty": 4, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Potion 2", + "id": 88873623, + "difficulty": 1, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Death 1 (Dif. 3)", + "id": 88873624, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Meat 2 (Dif. 4)", + "id": 88873625, + "difficulty": 4, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Dagger Peak Chest - Timestop 1 (Dif. 3)", + "id": 88873626, + "difficulty": 3, + "tags": [ + "dagger_peak" + ] + }, + { + "name": "Cliffs of Desolation - Scroll 1", + "id": 88870058, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Reflective Shot (Dif. 4)", + "id": 88870059, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation - Key 1 (Dif. 2)", + "id": 88870060, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 2 (Dif. 3)", + "id": 88870061, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Invisibility", + "id": 88870062, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation - Fire Potion 1 (Dif. 3)", + "id": 88870063, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation - Half Barrel of Gold 1 (Dif. 4)", + "id": 88870064, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Invulnerability (Dif. 4)", + "id": 88870065, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Rapid Fire (Dif. 3)", + "id": 88870066, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Half Barrel of Gold 2 (Dif. 3)", + "id": 88870067, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Large Pile of Gold 1", + "id": 88870068, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Meat Slab 1", + "id": 88870069, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Poison Fruit 1 (Dif. 4)", + "id": 88870070, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 3 (Dif. 4)", + "id": 88870071, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 4 (Dif. 3)", + "id": 88870072, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 5 (Dif. 4)", + "id": 88870073, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 6 (Dif. 2)", + "id": 88870074, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 7", + "id": 88870075, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Small Pile of Gold 1", + "id": 88870076, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Small Pile of Gold 2 (Dif. 2)", + "id": 88870077, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 8", + "id": 88870078, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 9", + "id": 88870079, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 10", + "id": 88870080, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 11 (Dif. 2)", + "id": 88870081, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 12 (Dif. 3)", + "id": 88870082, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 13 (Dif. 3)", + "id": 88870083, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 14", + "id": 88870084, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 15", + "id": 88870085, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation - Key 16", + "id": 88870086, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 17", + "id": 88870087, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 18 (Dif. 4)", + "id": 88870088, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 19", + "id": 88870089, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 20 (Dif. 2)", + "id": 88870090, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Full Barrel of Gold 1 (Dif. 4)", + "id": 88870091, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 21", + "id": 88870092, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 22 (Dif. 4)", + "id": 88870093, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation - Key 23", + "id": 88870094, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation - Key 24", + "id": 88870095, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation - Key 25", + "id": 88870096, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 26", + "id": 88870097, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Key 27", + "id": 88870098, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation - Obelisk", + "id": 88870613, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation", + "obelisk", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Key 1 (Dif. 3)", + "id": 8887370, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Death 1 (Dif. 3)", + "id": 8887371, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Random 1 (Dif. 2)", + "id": 8887372, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Shrink 1 (Dif. 2)", + "id": 8887373, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - 5-Way Shot 1 (Dif. 3)", + "id": 8887374, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Nothing 1", + "id": 8887375, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Nothing 2", + "id": 8887376, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Scroll 1", + "id": 8887377, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Nothing 3 (Dif. 2)", + "id": 8887378, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Potion 1 (Dif. 4)", + "id": 8887379, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Poison Fruit 1", + "id": 88873710, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Nothing 4 (Dif. 2)", + "id": 88873711, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Fruit 1", + "id": 88873712, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Key 2 (Dif. 2)", + "id": 88873713, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Key 3 (Dif. 2)", + "id": 88873714, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Fruit 2 (Dif. 2)", + "id": 88873715, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Poison Fruit 2 (Dif. 2)", + "id": 88873716, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Key 4 (Dif. 2)", + "id": 88873717, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Key 5", + "id": 88873718, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Key 6", + "id": 88873719, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Meat 1", + "id": 88873720, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Potion 2", + "id": 88873721, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Levitate 1 (Dif. 2)", + "id": 88873722, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Gold 1 (Dif. 2)", + "id": 88873723, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Fruit 1 (Dif. 3)", + "id": 88873724, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Death 1 (Dif. 4)", + "id": 88873725, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Gold 2 (Dif. 2)", + "id": 88873726, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation Chest - Potion 3", + "id": 88873727, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Gold 3", + "id": 88873728, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Death 2 (Dif. 2)", + "id": 88873729, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Gold 4 (Dif. 4)", + "id": 88873730, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Key 7", + "id": 88873731, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Gold 5 (Dif. 3)", + "id": 88873732, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Key 8", + "id": 88873733, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Potion 4", + "id": 88873734, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Meat 2 (Dif. 3)", + "id": 88873735, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Gold 6", + "id": 88873736, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Death 3", + "id": 88873737, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Meat 3 (Dif. 4)", + "id": 88873738, + "difficulty": 4, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Potion 5 (Dif. 2)", + "id": 88873739, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Dark Chest - Random 1 (Dif. 3)", + "id": 88873740, + "difficulty": 3, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Speed Boots 1", + "id": 88873741, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Potion 6", + "id": 88873742, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Key 9", + "id": 88873743, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation Chest - Meat 4 (Dif. 2)", + "id": 88873744, + "difficulty": 2, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Fire Amulet 1", + "id": 88873745, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Fruit 2", + "id": 88873746, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Cliffs of Desolation Barrel - Invulnerability 1", + "id": 88873747, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation" + ] + }, + { + "name": "Cliffs of Desolation Chest - Fruit 3", + "id": 88873748, + "difficulty": 1, + "tags": [ + "cliffs_of_desolation", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Scroll 1", + "id": 88870099, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Runestone", + "id": 88870100, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Very Small Pile of Gold 1 (Dif. 2)", + "id": 88870101, + "difficulty": 2, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Large Pile of Gold 1 (Dif. 4)", + "id": 88870102, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 1", + "id": 88870103, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Very Small Pile of Gold 2", + "id": 88870104, + "difficulty": 1, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Very Small Pile of Gold 3 (Dif. 3)", + "id": 88870105, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 2", + "id": 88870106, + "difficulty": 1, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Small Pile of Gold 1 (Dif. 2)", + "id": 88870107, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Half Barrel of Gold 1 (Dif. 3)", + "id": 88870108, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Large Pile of Gold 2", + "id": 88870109, + "difficulty": 1, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Key 3", + "id": 88870110, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 4 (Dif. 2)", + "id": 88870111, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Fire Potion 1", + "id": 88870112, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 5", + "id": 88870113, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 6 (Dif. 3)", + "id": 88870114, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Meat Slab 1 (Dif. 2)", + "id": 88870115, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 7 (Dif. 2)", + "id": 88870116, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Fruit 1 (Dif. 2)", + "id": 88870117, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Fire Potion 2 (Dif. 2)", + "id": 88870118, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Fruit 2", + "id": 88870119, + "difficulty": 1, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Key 8", + "id": 88870120, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 9", + "id": 88870121, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 10", + "id": 88870122, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 11 (Dif. 2)", + "id": 88870123, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Small Pile of Gold 2 (Dif. 2)", + "id": 88870124, + "difficulty": 2, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Large Pile of Gold 3 (Dif. 2)", + "id": 88870125, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Full Barrel of Gold 1 (Dif. 4)", + "id": 88870126, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Drumstick 1 (Dif. 2)", + "id": 88870127, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Drumstick 2 (Dif. 4)", + "id": 88870128, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 12 (Dif. 4)", + "id": 88870129, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 13 (Dif. 3)", + "id": 88870130, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 14 (Dif. 4)", + "id": 88870131, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 15 (Dif. 3)", + "id": 88870132, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 16 (Dif. 3)", + "id": 88870133, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 17", + "id": 88870134, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 18 (Dif. 2)", + "id": 88870135, + "difficulty": 2, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Key 19 (Dif. 3)", + "id": 88870136, + "difficulty": 3, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Key 20 (Dif. 4)", + "id": 88870137, + "difficulty": 4, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave - Fruit 3", + "id": 88870138, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Fruit 4 (Dif. 2)", + "id": 88870139, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Reflective Shot", + "id": 88870140, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Fire Breath", + "id": 88870141, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave - Key 21", + "id": 88870142, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Scroll 1", + "id": 8887380, + "difficulty": 1, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave Chest - Invulnerability 1 (Dif. 3)", + "id": 8887381, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Nothing 1 (Dif. 2)", + "id": 8887382, + "difficulty": 2, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave Chest - Gold 1", + "id": 8887383, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Gold 2 (Dif. 3)", + "id": 8887384, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Rapid Fire 1", + "id": 8887385, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Nothing 2", + "id": 8887386, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Speed Boots 1 (Dif. 4)", + "id": 8887387, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Fruit 1 (Dif. 2)", + "id": 8887388, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Dark Chest - Random 1", + "id": 8887389, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Gold 3", + "id": 88873810, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Fruit 1", + "id": 88873811, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Death 1", + "id": 88873812, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Potion 1", + "id": 88873813, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Meat 1 (Dif. 3)", + "id": 88873814, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Potion 1 (Dif. 3)", + "id": 88873815, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Potion 2 (Dif. 4)", + "id": 88873816, + "difficulty": 4, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave Chest - Meat 2", + "id": 88873817, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Fire Amulet 1", + "id": 88873818, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Gold 4 (Dif. 2)", + "id": 88873819, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Potion 2", + "id": 88873820, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Fruit 2 (Dif. 3)", + "id": 88873821, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Meat 1", + "id": 88873822, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Potion 3 (Dif. 2)", + "id": 88873823, + "difficulty": 2, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Lost Cave Barrel - Potion 4 (Dif. 4)", + "id": 88873824, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Potion 5 (Dif. 2)", + "id": 88873825, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Acid Breath 1 (Dif. 2)", + "id": 88873826, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Fruit 2 (Dif. 4)", + "id": 88873827, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Nothing 3", + "id": 88873828, + "difficulty": 1, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Poison Fruit 1 (Dif. 3)", + "id": 88873829, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Gold 5 (Dif. 4)", + "id": 88873830, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Poison Fruit 2 (Dif. 4)", + "id": 88873831, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Light Amulet 1 (Dif. 2)", + "id": 88873832, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - 3-Way Shot 1 (Dif. 2)", + "id": 88873833, + "difficulty": 2, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Reflective Shield 1 (Dif. 3)", + "id": 88873834, + "difficulty": 3, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Barrel - Super Shot 1 (Dif. 4)", + "id": 88873835, + "difficulty": 4, + "tags": [ + "lost_cave" + ] + }, + { + "name": "Lost Cave Chest - Gold 6", + "id": 88873836, + "difficulty": 1, + "tags": [ + "lost_cave", + "no_obelisks" + ] + }, + { + "name": "Volcanic Cavern - Key 1", + "id": 88870143, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Scimitar of Decapitation", + "id": 88870144, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Runestone", + "id": 88870145, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 2", + "id": 88870146, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 3 (Dif. 3)", + "id": 88870147, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Fire Potion 1", + "id": 88870148, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 4", + "id": 88870149, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 5", + "id": 88870150, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 6", + "id": 88870151, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 7 (Dif. 2)", + "id": 88870152, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 8 (Dif. 2)", + "id": 88870153, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 9", + "id": 88870154, + "difficulty": 1, + "tags": [ + "volcanic_cavern", + "no_obelisks" + ] + }, + { + "name": "Volcanic Cavern - Large Pile of Gold 1 (Dif. 2)", + "id": 88870155, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Small Pile of Gold 1", + "id": 88870156, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Half Barrel of Gold 1 (Dif. 3)", + "id": 88870157, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 10", + "id": 88870158, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 11 (Dif. 2)", + "id": 88870159, + "difficulty": 2, + "tags": [ + "volcanic_cavern", + "no_obelisks" + ] + }, + { + "name": "Volcanic Cavern - Key 12 (Dif. 3)", + "id": 88870160, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 13 (Dif. 2)", + "id": 88870161, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Very Small Pile of Gold 1", + "id": 88870162, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 14 (Dif. 2)", + "id": 88870163, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 15 (Dif. 3)", + "id": 88870164, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Full Barrel of Gold 2 (Dif. 4)", + "id": 88870165, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Small Pile of Gold 3", + "id": 88870166, + "difficulty": 1, + "tags": [ + "volcanic_cavern", + "no_obelisks" + ] + }, + { + "name": "Volcanic Cavern - Death (Dif. 2)", + "id": 88870167, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 16 (Dif. 3)", + "id": 88870168, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 17 (Dif. 4)", + "id": 88870169, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 18 (Dif. 3)", + "id": 88870170, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 19 (Dif. 4)", + "id": 88870171, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Key 20 (Dif. 2)", + "id": 88870172, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Fire Potion 2 (Dif. 4)", + "id": 88870173, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - 5-Way Shot (Dif. 4)", + "id": 88870174, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern - Invisibility (Dif. 3)", + "id": 88870175, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Key 1 (Dif. 4)", + "id": 8887390, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Key 2 (Dif. 3)", + "id": 8887391, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Key 3", + "id": 8887392, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Lightning Amulet 1", + "id": 8887393, + "difficulty": 1, + "tags": [ + "volcanic_cavern", + "no_obelisks" + ] + }, + { + "name": "Volcanic Cavern Chest - Lightning Shield 1", + "id": 8887394, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Fruit 1 (Dif. 4)", + "id": 8887395, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Meat 1", + "id": 8887396, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 1 (Dif. 4)", + "id": 8887397, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Scroll 1", + "id": 8887398, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Dark Chest - Random 1 (Dif. 3)", + "id": 8887399, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Death 1", + "id": 88873910, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Fruit 1", + "id": 88873911, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Potion 1 (Dif. 3)", + "id": 88873912, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Poison Fruit 1 (Dif. 3)", + "id": 88873913, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Super Shot 1", + "id": 88873914, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 2", + "id": 88873915, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Poison Fruit 1", + "id": 88873916, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Anti-Death Halo 1 (Dif. 2)", + "id": 88873917, + "difficulty": 2, + "tags": [ + "volcanic_cavern", + "no_obelisks" + ] + }, + { + "name": "Volcanic Cavern Chest - Potion 1 (Dif. 3)", + "id": 88873918, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - 3-Way Shot 1", + "id": 88873919, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Fruit 2 (Dif. 2)", + "id": 88873920, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Timestop 1 (Dif. 3)", + "id": 88873921, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Meat 2", + "id": 88873922, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Potion 2 (Dif. 2)", + "id": 88873923, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Meat 1", + "id": 88873924, + "difficulty": 1, + "tags": [ + "volcanic_cavern", + "no_obelisks" + ] + }, + { + "name": "Volcanic Cavern Chest - Potion 2 (Dif. 4)", + "id": 88873925, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Fruit 3 (Dif. 2)", + "id": 88873926, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Fruit 4 (Dif. 3)", + "id": 88873927, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Scroll 1", + "id": 88873928, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 3", + "id": 88873929, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Gold 1 (Dif. 3)", + "id": 88873930, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Gold 1 (Dif. 4)", + "id": 88873931, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Gold 2", + "id": 88873932, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Meat 3 (Dif. 2)", + "id": 88873933, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Fruit 2 (Dif. 4)", + "id": 88873934, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Meat 2 (Dif. 3)", + "id": 88873935, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Potion 3", + "id": 88873936, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Gold 3 (Dif. 2)", + "id": 88873937, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Lightning Breath 1 (Dif. 2)", + "id": 88873938, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Fruit 5 (Dif. 3)", + "id": 88873939, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Speed Boots 1 (Dif. 4)", + "id": 88873940, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Chest - Potion 3 (Dif. 2)", + "id": 88873941, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 4 (Dif. 3)", + "id": 88873942, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Potion 4", + "id": 88873943, + "difficulty": 1, + "tags": [ + "volcanic_cavern", + "no_obelisks" + ] + }, + { + "name": "Volcanic Cavern Barrel - Death 1 (Dif. 3)", + "id": 88873944, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Meat 3 (Dif. 4)", + "id": 88873945, + "difficulty": 4, + "tags": [ + "volcanic_cavern", + "no_obelisks" + ] + }, + { + "name": "Volcanic Cavern Chest - Phoenix Familiar 1 (Dif. 2)", + "id": 88873946, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 5 (Dif. 2)", + "id": 88873947, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 6 (Dif. 2)", + "id": 88873948, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 7 (Dif. 3)", + "id": 88873949, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 8", + "id": 88873950, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 9 (Dif. 4)", + "id": 88873951, + "difficulty": 4, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 10 (Dif. 2)", + "id": 88873952, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 11 (Dif. 3)", + "id": 88873953, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Scroll 2", + "id": 88873954, + "difficulty": 1, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 12 (Dif. 3)", + "id": 88873955, + "difficulty": 3, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Volcanic Cavern Barrel - Nothing 13 (Dif. 2)", + "id": 88873956, + "difficulty": 2, + "tags": [ + "volcanic_cavern" + ] + }, + { + "name": "Dragon's Lair - Slab of Meat (Dif. 2)", + "id": 88870176, + "difficulty": 2, + "tags": [ + "dragons_lair", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Dragon's Lair - Rapid Fire (Dif. 2)", + "id": 88870177, + "difficulty": 2, + "tags": [ + "dragons_lair", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Dragon's Lair - Growth (Dif. 4)", + "id": 88870178, + "difficulty": 4, + "tags": [ + "dragons_lair", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Dragon's Lair - Speed Boots (Dif. 3)", + "id": 88870179, + "difficulty": 3, + "tags": [ + "dragons_lair", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Dragon's Lair - 3-Way Shot", + "id": 88870180, + "difficulty": 1, + "tags": [ + "dragons_lair", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Dragon's Lair - Drumstick", + "id": 88870181, + "difficulty": 1, + "tags": [ + "dragons_lair", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Dragon's Lair - Dragon Mirror Shard", + "id": 88870607, + "difficulty": 1, + "tags": [ + "dragons_lair", + "no_obelisks", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Castle Courtyard - Runestone", + "id": 88870182, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 1", + "id": 88870183, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 2", + "id": 88870184, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 3", + "id": 88870185, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 4", + "id": 88870186, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 5", + "id": 88870187, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 6", + "id": 88870188, + "difficulty": 1, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard - Key 7", + "id": 88870189, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 8", + "id": 88870190, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 9", + "id": 88870191, + "difficulty": 1, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard - Scroll 1", + "id": 88870192, + "difficulty": 1, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard - Full Barrel of Gold 1 (Dif. 4)", + "id": 88870193, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Lightning Potion 1", + "id": 88870194, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 10", + "id": 88870195, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Lightning Potion 2 (Dif. 4)", + "id": 88870196, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Scroll 2", + "id": 88870197, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Poison Fruit 1", + "id": 88870198, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 11 (Dif. 2)", + "id": 88870199, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 12", + "id": 88870200, + "difficulty": 1, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard - Key 13 (Dif. 4)", + "id": 88870201, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 14 (Dif. 4)", + "id": 88870202, + "difficulty": 4, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard - Large Pile of Gold 1 (Dif. 2)", + "id": 88870203, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 15", + "id": 88870204, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 16 (Dif. 2)", + "id": 88870205, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Death 1", + "id": 88870206, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Death 2 (Dif. 3)", + "id": 88870207, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Invulnerability", + "id": 88870208, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Half Barrel of Gold 1 (Dif. 3)", + "id": 88870209, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Lightning Potion 3 (Dif. 2)", + "id": 88870210, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Timestop (Dif. 4)", + "id": 88870211, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Super Shot (Dif. 2)", + "id": 88870212, + "difficulty": 2, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard - Phoenix Familiar", + "id": 88870213, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Fire Breath (Dif. 2)", + "id": 88870214, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 17 (Dif. 2)", + "id": 88870215, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Key 18 (Dif. 3)", + "id": 88870216, + "difficulty": 3, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard - Key 19 (Dif. 4)", + "id": 88870217, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Lightning Shield", + "id": 88870218, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard - Obelisk", + "id": 88870616, + "difficulty": 1, + "tags": [ + "castle_courtyard", + "obelisk", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 1", + "id": 8887300, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Shrink 1 (Dif. 4)", + "id": 8887301, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 1 (Dif. 3)", + "id": 8887302, + "difficulty": 3, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 2", + "id": 8887303, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 3", + "id": 8887304, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Fruit 1", + "id": 8887305, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Potion 1", + "id": 8887306, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 4", + "id": 8887307, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 2 (Dif. 2)", + "id": 8887308, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Poison Fruit 1 (Dif. 2)", + "id": 8887309, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 5 (Dif. 2)", + "id": 88873010, + "difficulty": 2, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Barrel - Gold 1 (Dif. 3)", + "id": 88873011, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 3 (Dif. 2)", + "id": 88873012, + "difficulty": 2, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Chest - Scroll 1", + "id": 88873013, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Dark Chest - Random 1 (Dif. 4)", + "id": 88873014, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Gold 1 (Dif. 2)", + "id": 88873015, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Nothing 1", + "id": 88873016, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Reflective Shot 1", + "id": 88873017, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Gold 2", + "id": 88873018, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Death 1 (Dif. 2)", + "id": 88873019, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Speed Boots 1 (Dif. 3)", + "id": 88873020, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Invisibility 1 (Dif. 4)", + "id": 88873021, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 6", + "id": 88873022, + "difficulty": 1, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Barrel - Gold 2", + "id": 88873023, + "difficulty": 1, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 4 (Dif. 3)", + "id": 88873024, + "difficulty": 3, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Barrel - Fruit 2 (Dif. 3)", + "id": 88873025, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Scroll 2", + "id": 88873026, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Potion 1 (Dif. 3)", + "id": 88873027, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Gold 3 (Dif. 2)", + "id": 88873028, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 5 (Dif. 3)", + "id": 88873029, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 6", + "id": 88873030, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Meat 1 (Dif. 4)", + "id": 88873031, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Meat 2 (Dif. 3)", + "id": 88873032, + "difficulty": 3, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Chest - Gold 4 (Dif. 4)", + "id": 88873033, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Potion 2 (Dif. 3)", + "id": 88873034, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Meat 3 (Dif. 2)", + "id": 88873035, + "difficulty": 2, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Chest - Lightning Amulet 1 (Dif. 3)", + "id": 88873036, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Fruit 1 (Dif. 4)", + "id": 88873037, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 7 (Dif. 3)", + "id": 88873038, + "difficulty": 3, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Chest - Potion 3 (Dif. 4)", + "id": 88873039, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Gold 5", + "id": 88873040, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 8 (Dif. 3)", + "id": 88873041, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 9", + "id": 88873042, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Fruit 2 (Dif. 2)", + "id": 88873043, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Gold 3", + "id": 88873044, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Chest - Meat 4", + "id": 88873045, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 10 (Dif. 4)", + "id": 88873046, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - 3-Way Shot 1 (Dif. 2)", + "id": 88873047, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 7 (Dif. 4)", + "id": 88873048, + "difficulty": 4, + "tags": [ + "castle_courtyard", + "no_obelisks" + ] + }, + { + "name": "Castle Courtyard Barrel - Lightning Breath 1 (Dif. 3)", + "id": 88873049, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Poison Fruit 2 (Dif. 4)", + "id": 88873050, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 8 (Dif. 2)", + "id": 88873051, + "difficulty": 2, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 9 (Dif. 4)", + "id": 88873052, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 11 (Dif. 4)", + "id": 88873053, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 10 (Dif. 3)", + "id": 88873054, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 11 (Dif. 3)", + "id": 88873055, + "difficulty": 3, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Nothing 12", + "id": 88873056, + "difficulty": 1, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Castle Courtyard Barrel - Key 12 (Dif. 4)", + "id": 88873057, + "difficulty": 4, + "tags": [ + "castle_courtyard" + ] + }, + { + "name": "Dungeon of Torment - Lightning Potion 1 (Dif. 4)", + "id": 88870219, + "difficulty": 4, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Key 1", + "id": 88870220, + "difficulty": 1, + "tags": [ + "dungeon_of_torment", + "no_obelisks" + ] + }, + { + "name": "Dungeon of Torment - Runestone", + "id": 88870221, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Key 2 (Dif. 3)", + "id": 88870222, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Key 3", + "id": 88870223, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Key 4 (Dif. 2)", + "id": 88870224, + "difficulty": 2, + "tags": [ + "dungeon_of_torment", + "no_obelisks" + ] + }, + { + "name": "Dungeon of Torment - Key 5 (Dif. 3)", + "id": 88870225, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Key 6 (Dif. 4)", + "id": 88870226, + "difficulty": 4, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Very Small Pile of Gold 1", + "id": 88870227, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Small Pile of Gold 1 (Dif. 2)", + "id": 88870228, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Full Barrel of Gold 1 (Dif. 4)", + "id": 88870229, + "difficulty": 4, + "tags": [ + "dungeon_of_torment", + "no_obelisks" + ] + }, + { + "name": "Dungeon of Torment - Half Barrel of Gold 1 (Dif. 3)", + "id": 88870230, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Small Pile of Gold 2", + "id": 88870231, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Large Pile fo Gold 1 (Dif. 3)", + "id": 88870232, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Half Barrel of Gold 2 (Dif. 4)", + "id": 88870233, + "difficulty": 4, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Lightning Potion 2", + "id": 88870234, + "difficulty": 1, + "tags": [ + "dungeon_of_torment", + "no_obelisks" + ] + }, + { + "name": "Dungeon of Torment - Acid Amulet", + "id": 88870235, + "difficulty": 1, + "tags": [ + "dungeon_of_torment", + "no_obelisks" + ] + }, + { + "name": "Dungeon of Torment - Poison Fruit", + "id": 88870236, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Key 7 (Dif. 2)", + "id": 88870237, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Key 8", + "id": 88870238, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment - Obelisk", + "id": 88870617, + "difficulty": 1, + "tags": [ + "dungeon_of_torment", + "obelisk", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Dungeon of Torment Barrel - Nothing 1", + "id": 8887310, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Chest - Meat 1 (Dif. 4)", + "id": 8887311, + "difficulty": 4, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Chest - Meat 2 (Dif. 3)", + "id": 8887312, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Chest - Acid Amulet 1", + "id": 8887313, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Death 1", + "id": 8887314, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Chest - Invulnerability 1 (Dif. 4)", + "id": 8887315, + "difficulty": 4, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Key 1 (Dif. 3)", + "id": 8887316, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Key 2 (Dif. 2)", + "id": 8887317, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Nothing 2 (Dif. 4)", + "id": 8887318, + "difficulty": 4, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Nothing 3 (Dif. 3)", + "id": 8887319, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Nothing 4 (Dif. 4)", + "id": 88873110, + "difficulty": 4, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Fruit 1 (Dif. 2)", + "id": 88873111, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Super Shot 1 (Dif. 3)", + "id": 88873112, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Potion 1 (Dif. 2)", + "id": 88873113, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Gold 1 (Dif. 2)", + "id": 88873114, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Gold 2", + "id": 88873115, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Key 3 (Dif. 4)", + "id": 88873116, + "difficulty": 4, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Chest - Meat 3 (Dif. 2)", + "id": 88873117, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Chest - Meat 4", + "id": 88873118, + "difficulty": 1, + "tags": [ + "dungeon_of_torment", + "no_obelisks" + ] + }, + { + "name": "Dungeon of Torment Chest - Potion 1 (Dif. 3)", + "id": 88873119, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Chest - Fruit 1 (Dif. 3)", + "id": 88873120, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Dark Chest - Random 1 (Dif. 2)", + "id": 88873121, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Chest - Potion 2", + "id": 88873122, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Chest - Gold 1 (Dif. 2)", + "id": 88873123, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Fruit 2 (Dif. 4)", + "id": 88873124, + "difficulty": 4, + "tags": [ + "dungeon_of_torment", + "no_obelisks" + ] + }, + { + "name": "Dungeon of Torment Barrel - Reflective Shot 1 (Dif. 2)", + "id": 88873125, + "difficulty": 2, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Scroll 1", + "id": 88873126, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Nothing 5 (Dif. 3)", + "id": 88873127, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Nothing 6 (Dif. 2)", + "id": 88873128, + "difficulty": 2, + "tags": [ + "dungeon_of_torment", + "no_obelisks" + ] + }, + { + "name": "Dungeon of Torment Barrel - Nothing 7 (Dif. 3)", + "id": 88873129, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Nothing 8 (Dif. 3)", + "id": 88873130, + "difficulty": 3, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Dungeon of Torment Barrel - Scroll 2", + "id": 88873131, + "difficulty": 1, + "tags": [ + "dungeon_of_torment" + ] + }, + { + "name": "Tower Armory - Key 1 (Dif. 4)", + "id": 88870239, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 2", + "id": 88870240, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 3", + "id": 88870241, + "difficulty": 1, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory - Key 4", + "id": 88870242, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 5", + "id": 88870243, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 6", + "id": 88870244, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 7 (Dif. 4)", + "id": 88870245, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Slab of Meat 1", + "id": 88870246, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Lightning Potion 1 (Dif. 3)", + "id": 88870247, + "difficulty": 3, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory - Key 8 (Dif. 2)", + "id": 88870248, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 9", + "id": 88870249, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 10 (Dif. 2)", + "id": 88870250, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 11", + "id": 88870251, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 12 (Dif. 3)", + "id": 88870252, + "difficulty": 3, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory - Key 13", + "id": 88870253, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 14 (Dif. 2)", + "id": 88870254, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 15 (Dif. 3)", + "id": 88870255, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 16 (Dif. 3)", + "id": 88870256, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 17", + "id": 88870257, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 18 (Dif. 2)", + "id": 88870258, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 19 (Dif. 3)", + "id": 88870259, + "difficulty": 3, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory - Fruit 1", + "id": 88870260, + "difficulty": 1, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory - Potion Pile (Dif. 2)", + "id": 88870261, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Lightning Potion 2", + "id": 88870262, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Poison Fruit 1 (Dif. 3)", + "id": 88870263, + "difficulty": 3, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory - Key 20 (Dif. 2)", + "id": 88870264, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Slab of Meat 2 (Dif. 4)", + "id": 88870265, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Lightning Potion 3 (Dif. 4)", + "id": 88870266, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 21 (Dif. 2)", + "id": 88870267, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Fruit 2 (Dif. 2)", + "id": 88870268, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Fruit 3", + "id": 88870269, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Reflective Shot 1 (Dif. 2)", + "id": 88870270, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Death 1 (Dif. 3)", + "id": 88870271, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Very Small Pile of Gold 1 (Dif. 4)", + "id": 88870272, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Very Small Pile of Gold 2", + "id": 88870273, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Half Barrel of Gold 1 (Dif. 4)", + "id": 88870274, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Small Pile of Gold 1 (Dif. 2)", + "id": 88870275, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Large Pile of Gold 1 (Dif. 3)", + "id": 88870276, + "difficulty": 3, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory - Very Small Pile of Gold 3", + "id": 88870277, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 22 (Dif. 3)", + "id": 88870278, + "difficulty": 3, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory - Acid Breath 1", + "id": 88870279, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Runestone", + "id": 88870280, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 23", + "id": 88870281, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 24 (Dif. 2)", + "id": 88870282, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory - Key 25", + "id": 88870283, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Key 1 (Dif. 4)", + "id": 8887320, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Scroll 1", + "id": 8887321, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Light Amulet 1 (Dif. 4)", + "id": 8887322, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Poison Fruit 1 (Dif. 4)", + "id": 8887323, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Fire Breath 1 (Dif. 4)", + "id": 8887324, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Gold 1", + "id": 8887325, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Invisibility 1 (Dif. 2)", + "id": 8887326, + "difficulty": 2, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory Chest - Potion 1", + "id": 8887327, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Lightning Amulet 1", + "id": 8887328, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Poison Fruit 1", + "id": 8887329, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Meat 1 (Dif. 3)", + "id": 88873210, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Death 1 (Dif. 2)", + "id": 88873211, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Super Shot 1 (Dif. 3)", + "id": 88873212, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Growth 1 (Dif. 3)", + "id": 88873213, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Potion 2 (Dif. 2)", + "id": 88873214, + "difficulty": 2, + "tags": [ + "tower_armory", + "no_obelisks" + ] + }, + { + "name": "Tower Armory Chest - Death 2", + "id": 88873215, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Gold 2 (Dif. 3)", + "id": 88873216, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Gold 3 (Dif. 2)", + "id": 88873217, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Fruit 1 (Dif. 4)", + "id": 88873218, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Potion 3", + "id": 88873219, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Fruit 2 (Dif. 2)", + "id": 88873220, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Dark Chest - Random 1 (Dif. 3)", + "id": 88873221, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Meat 2", + "id": 88873222, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Scroll 2", + "id": 88873223, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - 3-Way Shot 1", + "id": 88873224, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Meat 3 (Dif. 2)", + "id": 88873225, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Invulnerability 1 (Dif. 4)", + "id": 88873226, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Gold 1", + "id": 88873227, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Key 2", + "id": 88873228, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Nothing 1 (Dif. 3)", + "id": 88873229, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Key 3 (Dif. 2)", + "id": 88873230, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Dark Chest - Random 2 (Dif. 2)", + "id": 88873231, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Scroll 3", + "id": 88873232, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Speed Boots 1", + "id": 88873233, + "difficulty": 1, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Levitate 1 (Dif. 3)", + "id": 88873234, + "difficulty": 3, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Barrel - Nothing 2 (Dif. 4)", + "id": 88873235, + "difficulty": 4, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Tower Armory Chest - Reflective Shield 1 (Dif. 2)", + "id": 88873236, + "difficulty": 2, + "tags": [ + "tower_armory" + ] + }, + { + "name": "Castle Treasury - Lightning Potion 1", + "id": 88870284, + "difficulty": 1, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Key 1", + "id": 88870285, + "difficulty": 1, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Key 2", + "id": 88870286, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 3", + "id": 88870287, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 4", + "id": 88870288, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 5", + "id": 88870289, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 6 (Dif. 3)", + "id": 88870290, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 7", + "id": 88870291, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 8", + "id": 88870292, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Half Barrel of Gold 1 (Dif. 4)", + "id": 88870293, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Very Small Pile of Gold 1 (Dif. 4)", + "id": 88870294, + "difficulty": 4, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Small Pile of Gold 1 (Dif. 4)", + "id": 88870295, + "difficulty": 4, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Full Barrel of Gold 1 (Dif. 4)", + "id": 88870296, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Large Pile of Gold 1 (Dif. 2)", + "id": 88870297, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Small Pile of Gold 2 (Dif. 3)", + "id": 88870298, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Scroll 1", + "id": 88870299, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Meat Slab 1 (Dif. 2)", + "id": 88870300, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Poison Fruit 1", + "id": 88870301, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Lightning Potion 2 (Dif. 4)", + "id": 88870302, + "difficulty": 4, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Key 9", + "id": 88870303, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Lightning Potion 3 (Dif. 2)", + "id": 88870304, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Bananas", + "id": 88870305, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Drumstick 1", + "id": 88870306, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Lightning Potion 4 (Dif. 3)", + "id": 88870307, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Lightning Potion 5", + "id": 88870308, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Pineapple (Dif. 2)", + "id": 88870309, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 10 (Dif. 2)", + "id": 88870310, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Poison Fruit 2 (Dif. 3)", + "id": 88870311, + "difficulty": 3, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Death 1 (Dif. 2)", + "id": 88870312, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Invulnerability 1 (Dif. 2)", + "id": 88870313, + "difficulty": 2, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Large Pile of Gold 2 (Dif. 4)", + "id": 88870314, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Very Small Pile of Gold 2", + "id": 88870315, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Half Barrel of Gold 2 (Dif. 3)", + "id": 88870316, + "difficulty": 3, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Very Small Pile of Gold 3 (Dif. 3)", + "id": 88870317, + "difficulty": 3, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Small Pile of Gold 3 (Dif. 2)", + "id": 88870318, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Large Pile of Gold 3 (Dif. 3)", + "id": 88870319, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Small Pile of Gold 4", + "id": 88870320, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Speed Boots 1 (Dif. 3)", + "id": 88870321, + "difficulty": 3, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury - Fruit 1 (Dif. 4)", + "id": 88870322, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 11 (Dif. 2)", + "id": 88870323, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 12 (Dif. 3)", + "id": 88870324, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 13 (Dif. 4)", + "id": 88870325, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Death 2 (Dif. 3)", + "id": 88870326, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Ice Axe of Untar", + "id": 88870327, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury - Key 14 (Dif. 4)", + "id": 88870328, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Scroll 1", + "id": 8887330, + "difficulty": 1, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury Barrel - Scroll 2", + "id": 8887331, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Key 1 (Dif. 2)", + "id": 8887332, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Key 2", + "id": 8887333, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Key 3", + "id": 8887334, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Key 4", + "id": 8887335, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Key 5 (Dif. 2)", + "id": 8887336, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Gold 1", + "id": 8887337, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Key 6 (Dif. 3)", + "id": 8887338, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Poison Fruit 1 (Dif. 3)", + "id": 8887339, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Key 7 (Dif. 4)", + "id": 88873310, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Gold 2", + "id": 88873311, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Gold 3", + "id": 88873312, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Potion 1 (Dif. 4)", + "id": 88873313, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Potion 2 (Dif. 3)", + "id": 88873314, + "difficulty": 3, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury Chest - Lightning Amulet 1", + "id": 88873315, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - 3-Way Shot 1 (Dif. 2)", + "id": 88873316, + "difficulty": 2, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury Chest - Potion 3", + "id": 88873317, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Dark Chest - Random 1 (Dif. 3)", + "id": 88873318, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Gold 4 (Dif. 2)", + "id": 88873319, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Potion 4 (Dif. 2)", + "id": 88873320, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Scroll 1", + "id": 88873321, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Meat 1 (Dif. 3)", + "id": 88873322, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Fruit 1 (Dif. 2)", + "id": 88873323, + "difficulty": 2, + "tags": [ + "castle_treasury", + "no_obelisks" + ] + }, + { + "name": "Castle Treasury Chest - Meat 2 (Dif. 4)", + "id": 88873324, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Thunder Hammer 1 (Dif. 4)", + "id": 88873325, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Timestop 1 (Dif. 4)", + "id": 88873326, + "difficulty": 4, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Levitate 1 (Dif. 3)", + "id": 88873327, + "difficulty": 3, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Lightning Shield 1", + "id": 88873328, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Death 1", + "id": 88873329, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Fire Shield 1", + "id": 88873330, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Barrel - Levitate 2 (Dif. 2)", + "id": 88873331, + "difficulty": 2, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Castle Treasury Chest - Random 1", + "id": 88873332, + "difficulty": 1, + "tags": [ + "castle_treasury" + ] + }, + { + "name": "Chimera's Keep - Speed Boots", + "id": 88870329, + "difficulty": 1, + "tags": [ + "chimeras_keep", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Chimera's Keep - Growth (Dif. 4)", + "id": 88870330, + "difficulty": 4, + "tags": [ + "chimeras_keep", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Chimera's Keep - 3-Way Shot (Dif. 2)", + "id": 88870331, + "difficulty": 2, + "tags": [ + "chimeras_keep", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Chimera's Keep - (Dif. 3)", + "id": 88870332, + "difficulty": 3, + "tags": [ + "chimeras_keep", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Chimera's Keep - Ham (Dif. 2)", + "id": 88870333, + "difficulty": 2, + "tags": [ + "chimeras_keep", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Chimera's Keep - Drumstick", + "id": 88870334, + "difficulty": 1, + "tags": [ + "chimeras_keep", + "no_obelisks", + "no_spawner" + ] + }, + { + "name": "Chimera's Keep - Chimera Mirror Shard", + "id": 88870608, + "difficulty": 1, + "tags": [ + "chimeras_keep", + "no_obelisks", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Poisoned Fields - Fruit Pile 1", + "id": 88870335, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Fruit Pile 2 (Dif. 4)", + "id": 88870336, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Fruit Pile 3 (Dif. 3)", + "id": 88870337, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Fruit Pile 4", + "id": 88870338, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Death 1", + "id": 88870339, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 1", + "id": 88870340, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 2 (Dif. 2)", + "id": 88870341, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 3 (Dif. 3)", + "id": 88870342, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 4", + "id": 88870343, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 5 (Dif. 3)", + "id": 88870344, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 6", + "id": 88870345, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 7 (Dif. 2)", + "id": 88870346, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 8", + "id": 88870347, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 9 (Dif. 3)", + "id": 88870348, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Fruit Pile 5 (Dif. 3)", + "id": 88870349, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Fruit Pile 6 (Dif. 2)", + "id": 88870350, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Fruit Pile 7 (Dif. 2)", + "id": 88870351, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Fruit Pile 8 (Dif. 4)", + "id": 88870352, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Acid Potion 1 (Dif. 4)", + "id": 88870353, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 10 (Dif. 2)", + "id": 88870354, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Shrink", + "id": 88870355, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Reflective Shield (Dif. 2)", + "id": 88870356, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Ham 1 (Dif. 3)", + "id": 88870357, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 11", + "id": 88870358, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 12", + "id": 88870359, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 13 (Dif. 3)", + "id": 88870360, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 14", + "id": 88870361, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 15 (Dif. 2)", + "id": 88870362, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 16", + "id": 88870363, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 17 (Dif. 4)", + "id": 88870364, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 18", + "id": 88870365, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Small Pile of Gold 1 (Dif. 3)", + "id": 88870366, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Bananas", + "id": 88870367, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Acid Potion 2 (Dif. 3)", + "id": 88870368, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Drumstick 1 (Dif. 3)", + "id": 88870369, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Potion Pile 1 (Dif. 2)", + "id": 88870370, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Small Pile of Gold 2 (Dif. 2)", + "id": 88870371, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Very Small Pile of Gold 1 (Dif. 4)", + "id": 88870372, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Half Barrel of Gold 1 (Dif. 3)", + "id": 88870373, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Key 19", + "id": 88870374, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Death 2 (Dif. 3)", + "id": 88870375, + "difficulty": 3, + "tags": [ + "poisoned_fields", + "no_obelisks" + ] + }, + { + "name": "Poisoned Fields - Fruit 1", + "id": 88870376, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Speed Boots 1 (Dif. 4)", + "id": 88870377, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Death 3", + "id": 88870378, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Small Pile of Gold 3", + "id": 88870379, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Full Barrel of Gold 1 (Dif. 4)", + "id": 88870380, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Phoenix Familiar 1 (Dif. 2)", + "id": 88870381, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields - Obelisk", + "id": 88870614, + "difficulty": 1, + "tags": [ + "poisoned_fields", + "obelisk", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Poisoned Fields Barrel - Scroll 1", + "id": 8887110, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Potion 1", + "id": 8887111, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 1", + "id": 8887112, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 2", + "id": 8887113, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 1", + "id": 8887114, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 3", + "id": 8887115, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 4", + "id": 8887116, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 5", + "id": 8887117, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Scroll 2", + "id": 8887118, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 2", + "id": 8887119, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Fruit 1 (Dif. 4)", + "id": 88871110, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Scroll 3", + "id": 88871111, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Meat 1 (Dif. 2)", + "id": 88871112, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Fruit 2 (Dif. 4)", + "id": 88871113, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Fruit 3 (Dif. 3)", + "id": 88871114, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 1 (Dif. 3)", + "id": 88871115, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 3", + "id": 88871116, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 6", + "id": 88871117, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 7", + "id": 88871118, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 8", + "id": 88871119, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 4 (Dif. 4)", + "id": 88871120, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 5 (Dif. 3)", + "id": 88871121, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 6", + "id": 88871122, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 7 (Dif. 2)", + "id": 88871123, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 8", + "id": 88871124, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 9", + "id": 88871125, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 10", + "id": 88871126, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 11", + "id": 88871127, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 9", + "id": 88871128, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Thunder Hammer 1 (Dif. 2)", + "id": 88871129, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Death 1", + "id": 88871130, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 10", + "id": 88871131, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Anti-Death Halo 1", + "id": 88871132, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Potion 1 (Dif. 2)", + "id": 88871133, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 2 (Dif. 2)", + "id": 88871134, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 3 (Dif. 2)", + "id": 88871135, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 4 (Dif. 2)", + "id": 88871136, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 5", + "id": 88871137, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 6 (Dif. 4)", + "id": 88871138, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 12", + "id": 88871139, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Gold 1 (Dif. 4)", + "id": 88871140, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Potion 2", + "id": 88871141, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 7", + "id": 88871142, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 8 (Dif. 3)", + "id": 88871143, + "difficulty": 3, + "tags": [ + "poisoned_fields", + "no_obelisks" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 9 (Dif. 3)", + "id": 88871144, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Fruit 4 (Dif. 2)", + "id": 88871145, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 11", + "id": 88871146, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 13", + "id": 88871147, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 14", + "id": 88871148, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - 3-Way Shot 1", + "id": 88871149, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Meat 2 (Dif. 2)", + "id": 88871150, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 15", + "id": 88871151, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 16", + "id": 88871152, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 12", + "id": 88871153, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Death 2 (Dif. 4)", + "id": 88871154, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 17", + "id": 88871155, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Lightning Shield 1 (Dif. 3)", + "id": 88871156, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Fire Amulet 1 (Dif. 3)", + "id": 88871157, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 10", + "id": 88871158, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Potion 2 (Dif. 4)", + "id": 88871159, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 11 (Dif. 3)", + "id": 88871160, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Meat 1", + "id": 88871161, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Speed Boots 1", + "id": 88871162, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 18", + "id": 88871163, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 19", + "id": 88871164, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 20", + "id": 88871165, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 21", + "id": 88871166, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Meat 3 (Dif. 4)", + "id": 88871167, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Rapid Fire 1 (Dif. 2)", + "id": 88871168, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Meat 2", + "id": 88871169, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Potion 3", + "id": 88871170, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 13", + "id": 88871171, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Gold 2", + "id": 88871172, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - 3-Way Shot 1 (Dif. 4)", + "id": 88871173, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Scroll 4", + "id": 88871174, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Nothing 22", + "id": 88871175, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 12 (Dif. 3)", + "id": 88871176, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Fruit 5 (Dif. 3)", + "id": 88871177, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 14 (Dif. 3)", + "id": 88871178, + "difficulty": 3, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Key 15", + "id": 88871179, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Potion 3 (Dif. 2)", + "id": 88871180, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Barrel - Death 3 (Dif. 2)", + "id": 88871181, + "difficulty": 2, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 13 (Dif. 4)", + "id": 88871182, + "difficulty": 4, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Poisoned Fields Chest - Gold 14", + "id": 88871183, + "difficulty": 1, + "tags": [ + "poisoned_fields" + ] + }, + { + "name": "Haunted Cemetery - Acid Potion 1", + "id": 88870382, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Runestone", + "id": 88870383, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Small Pile of Gold", + "id": 88870384, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Key 1 (Dif. 3)", + "id": 88870385, + "difficulty": 3, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Acid Potion 2", + "id": 88870386, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - 3-Way Shot", + "id": 88870387, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Key 2 (Dif. 2)", + "id": 88870388, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Key 3 (Dif. 3)", + "id": 88870389, + "difficulty": 3, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Key 4", + "id": 88870390, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Key 5 (Dif. 2)", + "id": 88870391, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Key 6", + "id": 88870392, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Key 7 (Dif. 2)", + "id": 88870393, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Speed Boots (Dif. 3)", + "id": 88870394, + "difficulty": 3, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery - Key 8 (Dif. 4)", + "id": 88870395, + "difficulty": 4, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Death 1", + "id": 88870396, + "difficulty": 1, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery - Phoenix Familiar", + "id": 88870397, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Timestop", + "id": 88870398, + "difficulty": 1, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery - Fire Amulet (Dif. 2)", + "id": 88870399, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery - Death 2 (Dif. 2)", + "id": 88870400, + "difficulty": 2, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery - Obelisk", + "id": 88870615, + "difficulty": 1, + "tags": [ + "haunted_cemetery", + "obelisk", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Haunted Cemetery Barrel - Invulnerability 1", + "id": 8887120, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Fire Shield 1 (Dif. 4)", + "id": 8887121, + "difficulty": 4, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Fruit 1 (Dif. 4)", + "id": 8887122, + "difficulty": 4, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Meat 1", + "id": 8887123, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Fruit 2 (Dif. 2)", + "id": 8887124, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Potion 1 (Dif. 4)", + "id": 8887125, + "difficulty": 4, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Key 1 (Dif. 2)", + "id": 8887126, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Potion 1 (Dif. 2)", + "id": 8887127, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Poison Fruit 1 (Dif. 4)", + "id": 8887128, + "difficulty": 4, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Key 2 (Dif. 2)", + "id": 8887129, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Dark Chest - Random 1 (Dif. 2)", + "id": 88871210, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Key 3 (Dif. 3)", + "id": 88871211, + "difficulty": 3, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Scroll 1", + "id": 88871212, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Poison Fruit 2 (Dif. 2)", + "id": 88871213, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Poison Fruit 3 (Dif. 3)", + "id": 88871214, + "difficulty": 3, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Rapid Fire 1 (Dif. 2)", + "id": 88871215, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Gold 1 (Dif. 4)", + "id": 88871216, + "difficulty": 4, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Shrink 1 (Dif. 3)", + "id": 88871217, + "difficulty": 3, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Potion 2 (Dif. 3)", + "id": 88871218, + "difficulty": 3, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Scroll 1", + "id": 88871219, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Scroll 2", + "id": 88871220, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Meat 2 (Dif. 3)", + "id": 88871221, + "difficulty": 3, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Meat 1 (Dif. 2)", + "id": 88871222, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Key 4 (Dif. 2)", + "id": 88871223, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Potion 2", + "id": 88871224, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Death 1 (Dif. 4)", + "id": 88871225, + "difficulty": 4, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery Barrel - Gold 1", + "id": 88871226, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Levitate 1", + "id": 88871227, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Fruit 3 (Dif. 3)", + "id": 88871228, + "difficulty": 3, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Gold 2 (Dif. 2)", + "id": 88871229, + "difficulty": 2, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery Chest - Fruit 1", + "id": 88871230, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Nothing 1", + "id": 88871231, + "difficulty": 1, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery Barrel - Key 5", + "id": 88871232, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Key 6", + "id": 88871233, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Gold 2 (Dif. 3)", + "id": 88871234, + "difficulty": 3, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery Barrel - Key 7 (Dif. 4)", + "id": 88871235, + "difficulty": 4, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Key 8", + "id": 88871236, + "difficulty": 1, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Barrel - Death 2", + "id": 88871237, + "difficulty": 1, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery Barrel - Gold 3 (Dif. 2)", + "id": 88871238, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Death 1 (Dif. 3)", + "id": 88871239, + "difficulty": 3, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - 3-Way Shot 1 (Dif. 2)", + "id": 88871240, + "difficulty": 2, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Haunted Cemetery Chest - Gold 3", + "id": 88871241, + "difficulty": 1, + "tags": [ + "haunted_cemetery", + "no_obelisks" + ] + }, + { + "name": "Haunted Cemetery Chest - Meat 2 (Dif. 4)", + "id": 88871242, + "difficulty": 4, + "tags": [ + "haunted_cemetery" + ] + }, + { + "name": "Venemous Spire - Acid Potion 1", + "id": 88870401, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Invisibility", + "id": 88870402, + "difficulty": 1, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire - Flame of Tarkana", + "id": 88870403, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Runestone", + "id": 88870404, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Super Shot", + "id": 88870405, + "difficulty": 1, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire - Death 1", + "id": 88870406, + "difficulty": 1, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire - Key 1 (Dif. 4)", + "id": 88870407, + "difficulty": 4, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Key 2 (Dif. 3)", + "id": 88870408, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Lightning Amulet (Dif. 2)", + "id": 88870409, + "difficulty": 2, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire - Pineapple (Dif. 3)", + "id": 88870410, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Half Barrel of Gold 1 (Dif. 3)", + "id": 88870411, + "difficulty": 3, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire - Death 2 (Dif. 2)", + "id": 88870412, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Key 3 (Dif. 3)", + "id": 88870413, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Key 4 (Dif. 2)", + "id": 88870414, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Phoenix Familiar (Dif. 4)", + "id": 88870415, + "difficulty": 4, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire - Key 5", + "id": 88870416, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Speed Boots 1", + "id": 8887130, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Potion 1", + "id": 8887131, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Poison Fruit 1 (Dif. 2)", + "id": 8887132, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Poison Fruit 2", + "id": 8887133, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 1 (Dif. 3)", + "id": 8887134, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Meat 1 (Dif. 3)", + "id": 8887135, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 2", + "id": 8887136, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Scroll 1", + "id": 8887137, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Scroll 1", + "id": 8887138, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Scroll 2", + "id": 8887139, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Scroll 3", + "id": 88871310, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Scroll 4", + "id": 88871311, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 3", + "id": 88871312, + "difficulty": 1, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire Barrel - Key 4 (Dif. 3)", + "id": 88871313, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 5", + "id": 88871314, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Scroll 5", + "id": 88871315, + "difficulty": 1, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire Barrel - Key 6 (Dif. 4)", + "id": 88871316, + "difficulty": 4, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire Barrel - Key 7", + "id": 88871317, + "difficulty": 1, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire Barrel - Key 8 (Dif. 4)", + "id": 88871318, + "difficulty": 4, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire Barrel - Key 9", + "id": 88871319, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 10", + "id": 88871320, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Acid Breath 1 (Dif. 2)", + "id": 88871321, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 11 (Dif. 2)", + "id": 88871322, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Speed Boots 1", + "id": 88871323, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 12", + "id": 88871324, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Gold 1 (Dif. 2)", + "id": 88871325, + "difficulty": 2, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire Barrel - Gold 2", + "id": 88871326, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Meat 1 (Dif. 2)", + "id": 88871327, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Potion 1", + "id": 88871328, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Dark Chest - Random 1", + "id": 88871329, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Fruit 1", + "id": 88871330, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Meat 2", + "id": 88871331, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Death 1", + "id": 88871332, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 13", + "id": 88871333, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Fruit 2 (Dif. 4)", + "id": 88871334, + "difficulty": 4, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Gold 3 (Dif. 3)", + "id": 88871335, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 14", + "id": 88871336, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Death 1 (Dif. 3)", + "id": 88871337, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Potion 2 (Dif. 3)", + "id": 88871338, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Death 2", + "id": 88871339, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Fruit 3 (Dif. 2)", + "id": 88871340, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Gold 1 (Dif. 3)", + "id": 88871341, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Speed Boots 2 (Dif. 3)", + "id": 88871342, + "difficulty": 3, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Gold 2 (Dif. 4)", + "id": 88871343, + "difficulty": 4, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Gold 3 (Dif. 4)", + "id": 88871344, + "difficulty": 4, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Gold 4 (Dif. 2)", + "id": 88871345, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Reflective Shield 1", + "id": 88871346, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Death 2 (Dif. 2)", + "id": 88871347, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Nothing 1", + "id": 88871348, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Nothing 2", + "id": 88871349, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Nothing 3", + "id": 88871350, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 15", + "id": 88871351, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Gold 5", + "id": 88871352, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Fire Shield 1", + "id": 88871353, + "difficulty": 1, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire Barrel - Key 16", + "id": 88871354, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Nothing 4", + "id": 88871355, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Meat 2 (Dif. 4)", + "id": 88871356, + "difficulty": 4, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 17 (Dif. 4)", + "id": 88871357, + "difficulty": 4, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire Barrel - Death 3 (Dif. 4)", + "id": 88871358, + "difficulty": 4, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Venemous Spire Chest - Potion 3 (Dif. 4)", + "id": 88871359, + "difficulty": 4, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Gold 4", + "id": 88871360, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 18", + "id": 88871361, + "difficulty": 1, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Chest - Gold 5 (Dif. 2)", + "id": 88871362, + "difficulty": 2, + "tags": [ + "venomous_spire" + ] + }, + { + "name": "Venemous Spire Barrel - Key 19", + "id": 88871363, + "difficulty": 1, + "tags": [ + "venomous_spire", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship - Acid Breath", + "id": 88870417, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Scroll", + "id": 88870418, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Key 1", + "id": 88870419, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Runestone", + "id": 88870420, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Phoenix Familiar", + "id": 88870421, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Key 2", + "id": 88870422, + "difficulty": 1, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship - Key 3 (Dif. 2)", + "id": 88870423, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Key 4 (Dif. 4)", + "id": 88870424, + "difficulty": 4, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Key 5 (Dif. 2)", + "id": 88870425, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Key 6", + "id": 88870426, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Poison Fruit 1 (Dif. 2)", + "id": 88870427, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Death (Dif. 2)", + "id": 88870428, + "difficulty": 2, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship - Bananas (Dif. 4)", + "id": 88870429, + "difficulty": 4, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship - Key 7", + "id": 88870430, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Key 8 (Dif. 2)", + "id": 88870431, + "difficulty": 2, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship - Key 9 (Dif. 3)", + "id": 88870432, + "difficulty": 3, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Poison Fruit 2 (Dif. 3)", + "id": 88870433, + "difficulty": 3, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Key 10", + "id": 88870434, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship - Fire Shield (Dif. 2)", + "id": 88870435, + "difficulty": 2, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 1 (Dif. 4)", + "id": 8887140, + "difficulty": 4, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 2 (Dif. 3)", + "id": 8887141, + "difficulty": 3, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Meat 1 (Dif. 4)", + "id": 8887142, + "difficulty": 4, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Potion 1", + "id": 8887143, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Meat 2 (Dif. 2)", + "id": 8887144, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Scroll 1", + "id": 8887145, + "difficulty": 1, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship Chest - Poison Fruit 1", + "id": 8887146, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Fruit 1", + "id": 8887147, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 3 (Dif. 2)", + "id": 8887148, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Growth 1 (Dif. 4)", + "id": 8887149, + "difficulty": 4, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Dark Chest - Random 1 (Dif. 2)", + "id": 88871410, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Scroll 1", + "id": 88871411, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Acid Amulet 1 (Dif. 2)", + "id": 88871412, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Gold 1 (Dif. 3)", + "id": 88871413, + "difficulty": 3, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Meat 3", + "id": 88871414, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Potion 1 (Dif. 3)", + "id": 88871415, + "difficulty": 3, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 4", + "id": 88871416, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Death 1 (Dif. 3)", + "id": 88871417, + "difficulty": 3, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship Chest - Gold 2 (Dif. 2)", + "id": 88871418, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - 3-Way Shot 1", + "id": 88871419, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Death 2 (Dif. 4)", + "id": 88871420, + "difficulty": 4, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 5", + "id": 88871421, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Gold 1 (Dif. 4)", + "id": 88871422, + "difficulty": 4, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship Barrel - Nothing 1", + "id": 88871423, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Potion 2 (Dif. 2)", + "id": 88871424, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 6", + "id": 88871425, + "difficulty": 1, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 7", + "id": 88871426, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Death 3", + "id": 88871427, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Nothing 2", + "id": 88871428, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 8", + "id": 88871429, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Gold 2 (Dif. 2)", + "id": 88871430, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 9 (Dif. 3)", + "id": 88871431, + "difficulty": 3, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Acid Breath 1 (Dif. 3)", + "id": 88871432, + "difficulty": 3, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Gold 3 (Dif. 4)", + "id": 88871433, + "difficulty": 4, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Gold 4 (Dif. 3)", + "id": 88871434, + "difficulty": 3, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Death 1", + "id": 88871435, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Gold 3", + "id": 88871436, + "difficulty": 1, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 10 (Dif. 2)", + "id": 88871437, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Key 11 (Dif. 4)", + "id": 88871438, + "difficulty": 4, + "tags": [ + "toxic_air_ship", + "no_obelisks" + ] + }, + { + "name": "Toxic Air Ship Chest - Poison Fruit 2 (Dif. 2)", + "id": 88871439, + "difficulty": 2, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Chest - Gold 5", + "id": 88871440, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Scroll 2", + "id": 88871441, + "difficulty": 1, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Meat 1 (Dif. 3)", + "id": 88871442, + "difficulty": 3, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Toxic Air Ship Barrel - Potion 3 (Dif. 4)", + "id": 88871443, + "difficulty": 4, + "tags": [ + "toxic_air_ship" + ] + }, + { + "name": "Vat of the Plague Fiend - Plague Fiend Mirror Shard", + "id": 88870609, + "difficulty": 1, + "tags": [ + "plague_fiend", + "no_obelisks", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Arctic Docks - Light Potion 1", + "id": 88870436, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Scroll", + "id": 88870437, + "difficulty": 1, + "tags": [ + "arctic_docks", + "no_obelisks" + ] + }, + { + "name": "Arctic Docks - Light Potion 2 (Dif. 2)", + "id": 88870438, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Small Pile of Gold (Dif. 2)", + "id": 88870439, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Fire Shield", + "id": 88870440, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 1", + "id": 88870441, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Meat", + "id": 88870442, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Light Potion 3 (Dif. 2)", + "id": 88870443, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Runestone", + "id": 88870444, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 2", + "id": 88870445, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 3 (Dif. 3)", + "id": 88870446, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 4", + "id": 88870447, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 5 (Dif. 2)", + "id": 88870448, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 6", + "id": 88870449, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 7", + "id": 88870450, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 8", + "id": 88870451, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 9", + "id": 88870452, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 10", + "id": 88870453, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 11", + "id": 88870454, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 12", + "id": 88870455, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 13 (Dif. 2)", + "id": 88870456, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 14 (Dif. 4)", + "id": 88870457, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 15", + "id": 88870458, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 16", + "id": 88870459, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Key 17", + "id": 88870460, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks - Speed Boots", + "id": 88870461, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 1", + "id": 8887160, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Phoenix Familiar 1", + "id": 8887161, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 1 (Dif. 2)", + "id": 8887162, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Potion 1 (Dif. 3)", + "id": 8887163, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Meat 1 (Dif. 3)", + "id": 8887164, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 2 (Dif. 2)", + "id": 8887165, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 3", + "id": 8887166, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 4 (Dif. 3)", + "id": 8887167, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Lightning Breath 1 (Dif. 2)", + "id": 8887168, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 5 (Dif. 4)", + "id": 8887169, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Meat 2 (Dif. 3)", + "id": 88871610, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 6 (Dif. 2)", + "id": 88871611, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 7", + "id": 88871612, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Meat 3", + "id": 88871613, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 2", + "id": 88871614, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 3", + "id": 88871615, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 4 (Dif. 2)", + "id": 88871616, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 5", + "id": 88871617, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Scroll 1", + "id": 88871618, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 6", + "id": 88871619, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Nothing 1", + "id": 88871620, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Rapid Fire 1 (Dif. 4)", + "id": 88871621, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Meat 1", + "id": 88871622, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Gold 1 (Dif. 2)", + "id": 88871623, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Acid Amulet 1 (Dif. 4)", + "id": 88871624, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 8", + "id": 88871625, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Death 1 (Dif. 2)", + "id": 88871626, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 7 (Dif. 4)", + "id": 88871627, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 8 (Dif. 2)", + "id": 88871628, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Potion 2 (Dif. 4)", + "id": 88871629, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Scroll 2", + "id": 88871630, + "difficulty": 1, + "tags": [ + "arctic_docks", + "no_obelisks" + ] + }, + { + "name": "Arctic Docks Barrel - Meat 4 (Dif. 4)", + "id": 88871631, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Nothing 2", + "id": 88871632, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Gold 1 (Dif. 4)", + "id": 88871633, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Phoenix Familiar 1 (Dif. 3)", + "id": 88871634, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 9 (Dif. 3)", + "id": 88871635, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 10", + "id": 88871636, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Death 2 (Dif. 3)", + "id": 88871637, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Nothing 3", + "id": 88871638, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Nothing 4", + "id": 88871639, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Nothing 5", + "id": 88871640, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Nothing 6", + "id": 88871641, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 11 (Dif. 2)", + "id": 88871642, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Reflective Shield 1 (Dif. 2)", + "id": 88871643, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 9 (Dif. 4)", + "id": 88871644, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Gold 2", + "id": 88871645, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Scroll 3", + "id": 88871646, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Fruit 10 (Dif. 3)", + "id": 88871647, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Gold 2 (Dif. 3)", + "id": 88871648, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Invisibility 1", + "id": 88871649, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Potion 1", + "id": 88871650, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Light Amulet 1 (Dif. 2)", + "id": 88871651, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Speed Boots 1 (Dif. 3)", + "id": 88871652, + "difficulty": 3, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Thunder Hammer 1 (Dif. 2)", + "id": 88871653, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - 3-Way Shot 1", + "id": 88871654, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Rapid Fire 1", + "id": 88871655, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Gold 3", + "id": 88871656, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 12", + "id": 88871657, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Death 1", + "id": 88871658, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Nothing 7", + "id": 88871659, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Nothing 8", + "id": 88871660, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Scroll 4", + "id": 88871661, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Gold 4 (Dif. 2)", + "id": 88871662, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Barrel - Key 13", + "id": 88871663, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Death 2", + "id": 88871664, + "difficulty": 1, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Meat 2 (Dif. 2)", + "id": 88871665, + "difficulty": 2, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Arctic Docks Chest - Meat 3 (Dif. 4)", + "id": 88871666, + "difficulty": 4, + "tags": [ + "arctic_docks" + ] + }, + { + "name": "Frozen Camp - Light Potion 1", + "id": 88870462, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Full Barrel of Gold 1 (Dif. 4)", + "id": 88870463, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Half Barrel of Gold 1", + "id": 88870464, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Scroll", + "id": 88870465, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Light Potion 2 (Dif. 2)", + "id": 88870466, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Light Potion 3", + "id": 88870467, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Large Pile of Gold 1 (Dif. 2)", + "id": 88870468, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Half Barrel of Gold 2 (Dif. 3)", + "id": 88870469, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Small Pile of Gold 1", + "id": 88870470, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Key 1 (Dif. 4)", + "id": 88870471, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Lightning Breath (Dif. 3)", + "id": 88870472, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Levitate (Dif. 2)", + "id": 88870473, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Key 2", + "id": 88870474, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Key 3 (Dif. 3)", + "id": 88870475, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Speed Boots", + "id": 88870476, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Key 4 (Dif. 3)", + "id": 88870477, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Key 5", + "id": 88870478, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Bananas (Dif. 4)", + "id": 88870479, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Pineapple", + "id": 88870480, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Light Potion 4 (Dif. 4)", + "id": 88870481, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Key 6 (Dif. 2)", + "id": 88870482, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Fruit 1 (Dif. 2)", + "id": 88870483, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Very Small Pile of Gold 1 (Dif. 2)", + "id": 88870484, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Very Small Pile of Gold 2", + "id": 88870485, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Drumstick (Dif. 4)", + "id": 88870486, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Very Small Pile of Gold 3 (Dif. 2)", + "id": 88870487, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Small Pile of Gold 2 (Dif. 2)", + "id": 88870488, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Very Small Pile of Gold 4 (Dif. 2)", + "id": 88870489, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Large Pile of Gold 2 (Dif. 3)", + "id": 88870490, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Growth", + "id": 88870491, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Runestone", + "id": 88870492, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Fruit 2", + "id": 88870493, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Phoenix Familiar", + "id": 88870494, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Death", + "id": 88870495, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Key 7", + "id": 88870496, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp - Key 8 (Dif. 4)", + "id": 88870497, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Scroll 1", + "id": 8887170, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Meat 1", + "id": 8887171, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 1", + "id": 8887172, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 2 (Dif. 2)", + "id": 8887173, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 3", + "id": 8887174, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 4", + "id": 8887175, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 5 (Dif. 2)", + "id": 8887176, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 1", + "id": 8887177, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 6", + "id": 8887178, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Meat 1 (Dif. 2)", + "id": 8887179, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Scroll 2", + "id": 88871710, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Nothing 1", + "id": 88871711, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Nothing 2", + "id": 88871712, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 7 (Dif. 2)", + "id": 88871713, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 8", + "id": 88871714, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Dark Chest - Random 1 (Dif. 2)", + "id": 88871715, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Death 1", + "id": 88871716, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 9 (Dif. 2)", + "id": 88871717, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 10", + "id": 88871718, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Rapid Fire 1 (Dif. 2)", + "id": 88871719, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 2", + "id": 88871720, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 11 (Dif. 2)", + "id": 88871721, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 12", + "id": 88871722, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 13", + "id": 88871723, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 14", + "id": 88871724, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 15 (Dif. 3)", + "id": 88871725, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 16 (Dif. 2)", + "id": 88871726, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 3 (Dif. 3)", + "id": 88871727, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 4 (Dif. 2)", + "id": 88871728, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 5 (Dif. 4)", + "id": 88871729, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 6", + "id": 88871730, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 7", + "id": 88871731, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 17", + "id": 88871732, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Super Shot 1", + "id": 88871733, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Invisibility 1 (Dif. 2)", + "id": 88871734, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Nothing 3", + "id": 88871735, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 8", + "id": 88871736, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Meat 2 (Dif. 3)", + "id": 88871737, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Gold 1 (Dif. 3)", + "id": 88871738, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Scroll 1", + "id": 88871739, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - 3-Way Shot 1 (Dif. 3)", + "id": 88871740, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Fruit 1 (Dif. 3)", + "id": 88871741, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Shrink 1 (Dif. 2)", + "id": 88871742, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 18", + "id": 88871743, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Speed Boots 1 (Dif. 4)", + "id": 88871744, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - 5-Way Shot 1 (Dif. 4)", + "id": 88871745, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Fruit 2 (Dif. 4)", + "id": 88871746, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 19 (Dif. 4)", + "id": 88871747, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Nothing 4", + "id": 88871748, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Nothing 5", + "id": 88871749, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Growth 1 (Dif. 4)", + "id": 88871750, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Potion 1", + "id": 88871751, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Fruit 1 (Dif. 2)", + "id": 88871752, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Scroll 3", + "id": 88871753, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 20", + "id": 88871754, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Potion 2 (Dif. 3)", + "id": 88871755, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Gold 2 (Dif. 4)", + "id": 88871756, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 21 (Dif. 3)", + "id": 88871757, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Reflective Shield 1", + "id": 88871758, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Thunder Hammer 1 (Dif. 2)", + "id": 88871759, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Lightning Amulet 1", + "id": 88871760, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Meat 3 (Dif. 2)", + "id": 88871761, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Potion 3 (Dif. 2)", + "id": 88871762, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Scroll 4", + "id": 88871763, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 22 (Dif. 2)", + "id": 88871764, + "difficulty": 2, + "tags": [ + "frozen_camp", + "no_obelisks" + ] + }, + { + "name": "Frozen Camp Chest - Gold 9 (Dif. 4)", + "id": 88871765, + "difficulty": 4, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Nothing 6", + "id": 88871766, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Fruit 3 (Dif. 3)", + "id": 88871767, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Acid Amulet 1", + "id": 88871768, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Gold 3 (Dif. 3)", + "id": 88871769, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Key 23", + "id": 88871770, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 10 (Dif. 2)", + "id": 88871771, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Meat 4", + "id": 88871772, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Potion 1 (Dif. 3)", + "id": 88871773, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Gold 11", + "id": 88871774, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Speed Boots 1 (Dif. 3)", + "id": 88871775, + "difficulty": 3, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Chest - Invulnerability 1", + "id": 88871776, + "difficulty": 1, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Frozen Camp Barrel - Death 1 (Dif. 2)", + "id": 88871777, + "difficulty": 2, + "tags": [ + "frozen_camp" + ] + }, + { + "name": "Crystal Mine - Rapid Fire", + "id": 88870498, + "difficulty": 1, + "tags": [ + "crystal_mine", + "no_obelisks" + ] + }, + { + "name": "Crystal Mine - Speed Boots", + "id": 88870499, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Key 1 (Dif. 2)", + "id": 88870500, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Key 2 (Dif. 4)", + "id": 88870501, + "difficulty": 4, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Key 3 (Dif. 3)", + "id": 88870502, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Lightning Breath", + "id": 88870503, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Key 4 (Dif. 2)", + "id": 88870504, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Key 5", + "id": 88870505, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Lightning Shield", + "id": 88870506, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Bananas", + "id": 88870507, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Key 6", + "id": 88870508, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Key 7", + "id": 88870509, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Runestone", + "id": 88870510, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine - Shrink (Dif. 3)", + "id": 88870511, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Reflective Shot 1 (Dif. 3)", + "id": 8887180, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Speed Boots 1 (Dif. 4)", + "id": 8887181, + "difficulty": 4, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Meat 1 (Dif. 2)", + "id": 8887182, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Meat 2", + "id": 8887183, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Meat 3 (Dif. 3)", + "id": 8887184, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Meat 4 (Dif. 2)", + "id": 8887185, + "difficulty": 2, + "tags": [ + "crystal_mine", + "no_obelisks" + ] + }, + { + "name": "Crystal Mine Barrel - Meat 5", + "id": 8887186, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Scroll 1", + "id": 8887187, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Growth 1 (Dif. 2)", + "id": 8887188, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 1", + "id": 8887189, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 2", + "id": 88871810, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 3 (Dif. 2)", + "id": 88871811, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 4 (Dif. 2)", + "id": 88871812, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 5 (Dif. 4)", + "id": 88871813, + "difficulty": 4, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Fruit 1", + "id": 88871814, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Gold 1 (Dif. 3)", + "id": 88871815, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Random 1 (Dif. 2)", + "id": 88871816, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Potion 1", + "id": 88871817, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Meat 1 (Dif. 4)", + "id": 88871818, + "difficulty": 4, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Gold 1 (Dif. 2)", + "id": 88871819, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Gold 2", + "id": 88871820, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 6", + "id": 88871821, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Gold 3 (Dif. 2)", + "id": 88871822, + "difficulty": 2, + "tags": [ + "crystal_mine", + "no_obelisks" + ] + }, + { + "name": "Crystal Mine Chest - Potion 1 (Dif. 4)", + "id": 88871823, + "difficulty": 4, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Gold 4", + "id": 88871824, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Gold 5", + "id": 88871825, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Fruit 1 (Dif. 2)", + "id": 88871826, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 7", + "id": 88871827, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Meat 2", + "id": 88871828, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Gold 2 (Dif. 2)", + "id": 88871829, + "difficulty": 2, + "tags": [ + "crystal_mine", + "no_obelisks" + ] + }, + { + "name": "Crystal Mine Barrel - Key 8", + "id": 88871830, + "difficulty": 1, + "tags": [ + "crystal_mine", + "no_obelisks" + ] + }, + { + "name": "Crystal Mine Barrel - Death 1 (Dif. 3)", + "id": 88871831, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 9 (Dif. 2)", + "id": 88871832, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Scroll 1", + "id": 88871833, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Nothing 1", + "id": 88871834, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Nothing 2", + "id": 88871835, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Potion 2 (Dif. 2)", + "id": 88871836, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 10", + "id": 88871837, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Gold 3 (Dif. 4)", + "id": 88871838, + "difficulty": 4, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Rapid Fire 1 (Dif. 2)", + "id": 88871839, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 11 (Dif. 3)", + "id": 88871840, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 12", + "id": 88871841, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Nothing 3", + "id": 88871842, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Nothing 4", + "id": 88871843, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Gold 6", + "id": 88871844, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Fruit 2 (Dif. 3)", + "id": 88871845, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 13 (Dif. 2)", + "id": 88871846, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Fruit 2", + "id": 88871847, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Gold 4 (Dif. 3)", + "id": 88871848, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Scroll 2", + "id": 88871849, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Gold 7 (Dif. 2)", + "id": 88871850, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Potion 3 (Dif. 3)", + "id": 88871851, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Fruit 3 (Dif. 2)", + "id": 88871852, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Gold 5 (Dif. 4)", + "id": 88871853, + "difficulty": 4, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 14", + "id": 88871854, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Potion 4", + "id": 88871855, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 15", + "id": 88871856, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - 3-Way Shot 1", + "id": 88871857, + "difficulty": 1, + "tags": [ + "crystal_mine", + "no_obelisks" + ] + }, + { + "name": "Crystal Mine Barrel - Scroll 2", + "id": 88871858, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Gold 8", + "id": 88871859, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Fire Amulet 1", + "id": 88871860, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 16", + "id": 88871861, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Chest - Scroll 3", + "id": 88871862, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Gold 6 (Dif. 3)", + "id": 88871863, + "difficulty": 3, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Death 2 (Dif. 2)", + "id": 88871864, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Key 17", + "id": 88871865, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Potion 5", + "id": 88871866, + "difficulty": 1, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Fruit 3 (Dif. 4)", + "id": 88871867, + "difficulty": 4, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Crystal Mine Barrel - Gold 7 (Dif. 2)", + "id": 88871868, + "difficulty": 2, + "tags": [ + "crystal_mine" + ] + }, + { + "name": "Erupting Fissure - Light Potion", + "id": 88870512, + "difficulty": 1, + "tags": [ + "erupting_fissure", + "no_obelisks" + ] + }, + { + "name": "Erupting Fissure - Growth", + "id": 88870513, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Reflective Shield", + "id": 88870514, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Key 1", + "id": 88870515, + "difficulty": 1, + "tags": [ + "erupting_fissure", + "no_obelisks" + ] + }, + { + "name": "Erupting Fissure - Key 2", + "id": 88870516, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - 3-Way Shot", + "id": 88870517, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Key 3", + "id": 88870518, + "difficulty": 1, + "tags": [ + "erupting_fissure", + "no_obelisks" + ] + }, + { + "name": "Erupting Fissure - Key 4", + "id": 88870519, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Key 5", + "id": 88870520, + "difficulty": 1, + "tags": [ + "erupting_fissure", + "no_obelisks" + ] + }, + { + "name": "Erupting Fissure - Death", + "id": 88870521, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Key 6", + "id": 88870522, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Key 7 (Dif. 2)", + "id": 88870523, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Key 8", + "id": 88870524, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Marker's Javelin", + "id": 88870525, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Rapid Fire", + "id": 88870526, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Speed Boots (Dif. 4)", + "id": 88870527, + "difficulty": 4, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Key 9", + "id": 88870528, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure - Key 10 (Dif. 2)", + "id": 88870529, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Meat 1", + "id": 8887190, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Potion 1 (Dif. 4)", + "id": 8887191, + "difficulty": 4, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Thunder Hammer 1 (Dif. 2)", + "id": 8887192, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Fruit 1 (Dif. 4)", + "id": 8887193, + "difficulty": 4, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Scroll 1", + "id": 8887194, + "difficulty": 1, + "tags": [ + "erupting_fissure", + "no_obelisks" + ] + }, + { + "name": "Erupting Fissure Barrel - Meat 2 (Dif. 4)", + "id": 8887195, + "difficulty": 4, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Fruit 2", + "id": 8887196, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Meat 3 (Dif. 2)", + "id": 8887197, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Scroll 2", + "id": 8887198, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Scroll 3", + "id": 8887199, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Fruit 3", + "id": 88871910, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Meat 4 (Dif. 3)", + "id": 88871911, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Fruit 4 (Dif. 2)", + "id": 88871912, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Meat 5", + "id": 88871913, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Scroll 4", + "id": 88871914, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 1", + "id": 88871915, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 2 (Dif. 2)", + "id": 88871916, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 3 (Dif. 2)", + "id": 88871917, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Dark Chest - Random 1 (Dif. 2)", + "id": 88871918, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Nothing 1", + "id": 88871919, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Nothing 2", + "id": 88871920, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Nothing 3", + "id": 88871921, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Nothing 4", + "id": 88871922, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Fruit 5 (Dif. 3)", + "id": 88871923, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Acid Amulet 1 (Dif. 4)", + "id": 88871924, + "difficulty": 4, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Nothing 5", + "id": 88871925, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Nothing 6", + "id": 88871926, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Gold 1 (Dif. 2)", + "id": 88871927, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 4 (Dif. 3)", + "id": 88871928, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 5", + "id": 88871929, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Fire Breath 1 (Dif. 3)", + "id": 88871930, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 6", + "id": 88871931, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Potion 1 (Dif. 3)", + "id": 88871932, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 7 (Dif. 3)", + "id": 88871933, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 8 (Dif. 4)", + "id": 88871934, + "difficulty": 4, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 9 (Dif. 3)", + "id": 88871935, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Fruit 6 (Dif. 2)", + "id": 88871936, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Death 1", + "id": 88871937, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Gold 2 (Dif. 3)", + "id": 88871938, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Meat 1 (Dif. 2)", + "id": 88871939, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 10 (Dif. 3)", + "id": 88871940, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 11 (Dif. 2)", + "id": 88871941, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 12", + "id": 88871942, + "difficulty": 1, + "tags": [ + "erupting_fissure", + "no_obelisks" + ] + }, + { + "name": "Erupting Fissure Chest - Gold 3", + "id": 88871943, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 13", + "id": 88871944, + "difficulty": 1, + "tags": [ + "erupting_fissure", + "no_obelisks" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 14", + "id": 88871945, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 15", + "id": 88871946, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 16", + "id": 88871947, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Death 2 (Dif. 3)", + "id": 88871948, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 17 (Dif. 3)", + "id": 88871949, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 18 (Dif. 2)", + "id": 88871950, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 19", + "id": 88871951, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 20 (Dif. 2)", + "id": 88871952, + "difficulty": 2, + "tags": [ + "erupting_fissure", + "no_obelisks" + ] + }, + { + "name": "Erupting Fissure Chest - Gold 4 (Dif. 2)", + "id": 88871953, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Scroll 5", + "id": 88871954, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Potion 2", + "id": 88871955, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Light Amulet 1 (Dif. 2)", + "id": 88871956, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Gold 1 (Dif. 4)", + "id": 88871957, + "difficulty": 4, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 21 (Dif. 2)", + "id": 88871958, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Fruit 7 (Dif. 4)", + "id": 88871959, + "difficulty": 4, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Fruit 8 (Dif. 3)", + "id": 88871960, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Gold 2", + "id": 88871961, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Key 22", + "id": 88871962, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Gold 3 (Dif. 3)", + "id": 88871963, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Gold 5", + "id": 88871964, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Potion 3 (Dif. 2)", + "id": 88871965, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Dark Chest - Random 2 (Dif. 3)", + "id": 88871966, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Invulnerability 1 (Dif. 2)", + "id": 88871967, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Invisibility 1", + "id": 88871968, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Fruit 1", + "id": 88871969, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Gold 6 (Dif. 4)", + "id": 88871970, + "difficulty": 4, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Gold 7", + "id": 88871971, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Super Shot 1 (Dif. 3)", + "id": 88871972, + "difficulty": 3, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Timestop 1", + "id": 88871973, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Potion 2", + "id": 88871974, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Barrel - Death 3 (Dif. 2)", + "id": 88871975, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Levitate 1", + "id": 88871976, + "difficulty": 1, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Erupting Fissure Chest - Gold 8 (Dif. 2)", + "id": 88871977, + "difficulty": 2, + "tags": [ + "erupting_fissure" + ] + }, + { + "name": "Yeti's Cavern - Yeti Mirror Shard", + "id": 88870610, + "difficulty": 1, + "tags": [ + "yeti", + "no_obelisks", + "skipped_local", + "no_spawner" + ] + }, + { + "name": "Desecrated Temple - Death 1", + "id": 88870530, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple - Death 2 (Dif. 2)", + "id": 88870531, + "difficulty": 2, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple - Speed Boots", + "id": 88870532, + "difficulty": 1, + "tags": [ + "desecrated_temple", + "no_obelisks" + ] + }, + { + "name": "Desecrated Temple - Reflective Shot", + "id": 88870533, + "difficulty": 1, + "tags": [ + "desecrated_temple", + "no_obelisks" + ] + }, + { + "name": "Desecrated Temple - Fire Amulet", + "id": 88870534, + "difficulty": 1, + "tags": [ + "desecrated_temple", + "no_obelisks" + ] + }, + { + "name": "Desecrated Temple - 3-Way Shot", + "id": 88870535, + "difficulty": 1, + "tags": [ + "desecrated_temple", + "no_obelisks" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 1 (Dif. 2)", + "id": 8887200, + "difficulty": 2, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 2 (Dif. 2)", + "id": 8887201, + "difficulty": 2, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 3 (Dif. 2)", + "id": 8887202, + "difficulty": 2, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 4 (Dif. 3)", + "id": 8887203, + "difficulty": 3, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 5 (Dif. 4)", + "id": 8887204, + "difficulty": 4, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 6", + "id": 8887205, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 7 (Dif. 2)", + "id": 8887206, + "difficulty": 2, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 8 (Dif. 2)", + "id": 8887207, + "difficulty": 2, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 9", + "id": 8887208, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 10", + "id": 8887209, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 11 (Dif. 3)", + "id": 88872010, + "difficulty": 3, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 12 (Dif. 2)", + "id": 88872011, + "difficulty": 2, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 13 (Dif. 4)", + "id": 88872012, + "difficulty": 4, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 14", + "id": 88872013, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 15 (Dif. 4)", + "id": 88872014, + "difficulty": 4, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Dark Chest - Random 1 (Dif. 3)", + "id": 88872015, + "difficulty": 3, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Dark Chest - Random 2 (Dif. 2)", + "id": 88872016, + "difficulty": 2, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 16 (Dif. 4)", + "id": 88872017, + "difficulty": 4, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 17", + "id": 88872018, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 18 (Dif. 2)", + "id": 88872019, + "difficulty": 2, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 19 (Dif. 3)", + "id": 88872020, + "difficulty": 3, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 20 (Dif. 3)", + "id": 88872021, + "difficulty": 3, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 21", + "id": 88872022, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 22", + "id": 88872023, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 23 (Dif. 4)", + "id": 88872024, + "difficulty": 4, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 24", + "id": 88872025, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 25", + "id": 88872026, + "difficulty": 1, + "tags": [ + "desecrated_temple", + "no_obelisks" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 26", + "id": 88872027, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 27", + "id": 88872028, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 28", + "id": 88872029, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Gold 29", + "id": 88872030, + "difficulty": 1, + "tags": [ + "desecrated_temple" + ] + }, + { + "name": "Desecrated Temple Chest - Levitate 1 (Dif. 2)", + "id": 88872031, + "difficulty": 2, + "tags": [ + "desecrated_temple", + "no_obelisks" + ] + }, + { + "name": "Desecrated Temple Chest - Phoenix Familiar 1 (Dif. 3)", + "id": 88872032, + "difficulty": 3, + "tags": [ + "desecrated_temple", + "no_obelisks" + ] + }, + { + "name": "Altar of Skorne - Skorne's Mask", + "id": 88872033, + "difficulty": 1, + "tags": [ + "altar_of_skorne", + "no_obelisks" + ] + }, + { + "name": "Altar of Skorne - Skorne's Horns", + "id": 88872034, + "difficulty": 1, + "tags": [ + "altar_of_skorne", + "no_obelisks" + ] + }, + { + "name": "Altar of Skorne - Skorne's Left Gauntlet", + "id": 88872035, + "difficulty": 1, + "tags": [ + "altar_of_skorne", + "no_obelisks" + ] + }, + { + "name": "Altar of Skorne - Skorne's Right Gauntlet", + "id": 88872036, + "difficulty": 1, + "tags": [ + "altar_of_skorne", + "no_obelisks" + ] + }, + { + "name": "Battle Trenches - Fire Potion 1", + "id": 88870536, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Light Potion", + "id": 88870537, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Scroll 1", + "id": 88870538, + "difficulty": 1, + "tags": [ + "battle_trenches", + "no_obelisks" + ] + }, + { + "name": "Battle Trenches - Fruit 1 (Dif. 2)", + "id": 88870539, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Key 1 (Dif. 3)", + "id": 88870540, + "difficulty": 3, + "tags": [ + "battle_trenches", + "no_obelisks" + ] + }, + { + "name": "Battle Trenches - Invisibility (Dif. 2)", + "id": 88870541, + "difficulty": 2, + "tags": [ + "battle_trenches", + "no_obelisks" + ] + }, + { + "name": "Battle Trenches - Speed Boots (Dif. 3)", + "id": 88870542, + "difficulty": 3, + "tags": [ + "battle_trenches", + "no_obelisks" + ] + }, + { + "name": "Battle Trenches - Key 2", + "id": 88870543, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Key 3", + "id": 88870544, + "difficulty": 1, + "tags": [ + "battle_trenches", + "no_obelisks" + ] + }, + { + "name": "Battle Trenches - Fruit 2", + "id": 88870545, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Anti-Death Halo", + "id": 88870546, + "difficulty": 1, + "tags": [ + "battle_trenches", + "no_obelisks" + ] + }, + { + "name": "Battle Trenches - Scroll 2", + "id": 88870547, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Key 4", + "id": 88870548, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Death (Dif. 2)", + "id": 88870549, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Bananas (Dif. 4)", + "id": 88870550, + "difficulty": 4, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Fruit 3", + "id": 88870551, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Key 5 (Dif. 3)", + "id": 88870552, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Key 6 (Dif. 2)", + "id": 88870553, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Fire Potion 2", + "id": 88870554, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Shrink", + "id": 88870555, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Fire Amulet", + "id": 88870556, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - 3-Way Shot (Dif. 2)", + "id": 88870557, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Rapid Fire (Dif. 2)", + "id": 88870558, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches - Reflective Shot", + "id": 88870559, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - 3-Way Shot 1", + "id": 8887210, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Potion 1 (Dif. 4)", + "id": 8887211, + "difficulty": 4, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Reflective Shot 1 (Dif. 4)", + "id": 8887212, + "difficulty": 4, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Levitate 1", + "id": 8887213, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Scroll 1", + "id": 8887214, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Gold 1 (Dif. 4)", + "id": 8887215, + "difficulty": 4, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Scroll 2", + "id": 8887216, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Scroll 3", + "id": 8887217, + "difficulty": 1, + "tags": [ + "battle_trenches", + "no_obelisks" + ] + }, + { + "name": "Battle Trenches Barrel - Key 1 (Dif. 3)", + "id": 8887218, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 2", + "id": 8887219, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 3", + "id": 88872110, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 4", + "id": 88872111, + "difficulty": 1, + "tags": [ + "battle_trenches", + "no_obelisks" + ] + }, + { + "name": "Battle Trenches Barrel - Key 5", + "id": 88872112, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Death 1", + "id": 88872113, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Gold 2", + "id": 88872114, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Fruit 1 (Dif. 3)", + "id": 88872115, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 6", + "id": 88872116, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Gold 3", + "id": 88872117, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Death 2 (Dif. 4)", + "id": 88872118, + "difficulty": 4, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 7 (Dif. 3)", + "id": 88872119, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 8 (Dif. 2)", + "id": 88872120, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Death 3 (Dif. 2)", + "id": 88872121, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Potion 1 (Dif. 2)", + "id": 88872122, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Gold 1 (Dif. 3)", + "id": 88872123, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Meat 1", + "id": 88872124, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Fire Breath 1 (Dif. 2)", + "id": 88872125, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 9 (Dif. 2)", + "id": 88872126, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Gold 4 (Dif. 2)", + "id": 88872127, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 10 (Dif. 2)", + "id": 88872128, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 11", + "id": 88872129, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 12 (Dif. 2)", + "id": 88872130, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Potion 2", + "id": 88872131, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Gold 5 (Dif. 3)", + "id": 88872132, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 13", + "id": 88872133, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Meat 2 (Dif. 2)", + "id": 88872134, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Thunder Hammer 1", + "id": 88872135, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Gold 2", + "id": 88872136, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 14", + "id": 88872137, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 15 (Dif. 2)", + "id": 88872138, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Meat 3", + "id": 88872139, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 16 (Dif. 3)", + "id": 88872140, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Death 4 (Dif. 3)", + "id": 88872141, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Meat 1 (Dif. 4)", + "id": 88872142, + "difficulty": 4, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 17", + "id": 88872143, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Gold 6 (Dif. 2)", + "id": 88872144, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Phoenix Familiar 1", + "id": 88872145, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 18", + "id": 88872146, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Speed Boots 1 (Dif. 4)", + "id": 88872147, + "difficulty": 4, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Gold 7 (Dif. 2)", + "id": 88872148, + "difficulty": 2, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 19 (Dif. 4)", + "id": 88872149, + "difficulty": 4, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Potion 3 (Dif. 3)", + "id": 88872150, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Gold 3", + "id": 88872151, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 20", + "id": 88872152, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Barrel - Key 21", + "id": 88872153, + "difficulty": 1, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Fire Amulet 1 (Dif. 3)", + "id": 88872154, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Battle Trenches Chest - Meat 4 (Dif. 3)", + "id": 88872155, + "difficulty": 3, + "tags": [ + "battle_trenches" + ] + }, + { + "name": "Fortified Towers - Meat (Dif. 3)", + "id": 88870560, + "difficulty": 3, + "tags": [ + "fortified_towers", + "no_obelisks" + ] + }, + { + "name": "Fortified Towers - Key 1", + "id": 88870561, + "difficulty": 1, + "tags": [ + "fortified_towers", + "no_obelisks" + ] + }, + { + "name": "Fortified Towers - Large Pile of Gold (Dif. 3)", + "id": 88870562, + "difficulty": 3, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers - Small Pile of Gold (Dif. 2)", + "id": 88870563, + "difficulty": 2, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers - Reflective Shot (Dif. 2)", + "id": 88870564, + "difficulty": 2, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers - Key 2", + "id": 88870565, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers - Soul Savior", + "id": 88870566, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Fire Breath 1 (Dif. 4)", + "id": 8887220, + "difficulty": 4, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Scroll 1", + "id": 8887221, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Invulnerability 1", + "id": 8887222, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Thunder Hammer 1 (Dif. 2)", + "id": 8887223, + "difficulty": 2, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Reflective Shield 1", + "id": 8887224, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Potion 1 (Dif. 4)", + "id": 8887225, + "difficulty": 4, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Key 1 (Dif. 2)", + "id": 8887226, + "difficulty": 2, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Key 2 (Dif. 4)", + "id": 8887227, + "difficulty": 4, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Potion 2 (Dif. 2)", + "id": 8887228, + "difficulty": 2, + "tags": [ + "fortified_towers", + "no_obelisks" + ] + }, + { + "name": "Fortified Towers Dark Chest - Random 1 (Dif. 3)", + "id": 8887229, + "difficulty": 3, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Fruit 1", + "id": 88872210, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Scroll 2", + "id": 88872211, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Gold 1 (Dif. 4)", + "id": 88872212, + "difficulty": 4, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Scroll 3", + "id": 88872213, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Key 3", + "id": 88872214, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Key 4", + "id": 88872215, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Scroll 4", + "id": 88872216, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Key 5", + "id": 88872217, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Fruit 2 (Dif. 3)", + "id": 88872218, + "difficulty": 3, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Gold 2", + "id": 88872219, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Potion 3 (Dif. 3)", + "id": 88872220, + "difficulty": 3, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Key 6 (Dif. 3)", + "id": 88872221, + "difficulty": 3, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Meat 1 (Dif. 4)", + "id": 88872222, + "difficulty": 4, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Speed Boots 1 (Dif. 3)", + "id": 88872223, + "difficulty": 3, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Phoenix Familiar 1 (Dif. 2)", + "id": 88872224, + "difficulty": 2, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Fruit 1 (Dif. 4)", + "id": 88872225, + "difficulty": 4, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Gold 1", + "id": 88872226, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Meat 2", + "id": 88872227, + "difficulty": 1, + "tags": [ + "fortified_towers", + "no_obelisks" + ] + }, + { + "name": "Fortified Towers Barrel - 3-Way Shot 1 (Dif. 3)", + "id": 88872228, + "difficulty": 3, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Death 1 (Dif. 2)", + "id": 88872229, + "difficulty": 2, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Gold 3", + "id": 88872230, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Fruit 3 (Dif. 2)", + "id": 88872231, + "difficulty": 2, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Key 7 (Dif. 3)", + "id": 88872232, + "difficulty": 3, + "tags": [ + "fortified_towers", + "no_obelisks" + ] + }, + { + "name": "Fortified Towers Barrel - Gold 4 (Dif. 3)", + "id": 88872233, + "difficulty": 3, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Key 8", + "id": 88872234, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Nothing 1", + "id": 88872235, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Potion 1", + "id": 88872236, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Key 9 (Dif. 2)", + "id": 88872237, + "difficulty": 2, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Barrel - Rapid Fire 1", + "id": 88872238, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Fruit 2", + "id": 88872239, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Meat 1 (Dif. 2)", + "id": 88872240, + "difficulty": 2, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Meat 2", + "id": 88872241, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Fortified Towers Chest - Fire Breath 1", + "id": 88872242, + "difficulty": 1, + "tags": [ + "fortified_towers" + ] + }, + { + "name": "Infernal Fortress - Thunder Hammer", + "id": 88870567, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Key 1 (Dif. 2)", + "id": 88870568, + "difficulty": 2, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Runestone", + "id": 88870569, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Drumstick (Dif. 4)", + "id": 88870570, + "difficulty": 4, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Large Pile of Gold (Dif. 3)", + "id": 88870571, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Very Small Pile of Gold 1", + "id": 88870572, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Half Barrel of Gold 1 (Dif. 4)", + "id": 88870573, + "difficulty": 4, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress - Light Potion", + "id": 88870574, + "difficulty": 1, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress - Key 2 (Dif. 2)", + "id": 88870575, + "difficulty": 2, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress - Death", + "id": 88870576, + "difficulty": 1, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress - Fruit", + "id": 88870577, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Small Pile of Gold (Dif. 2)", + "id": 88870578, + "difficulty": 2, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Key 3", + "id": 88870579, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Key 4", + "id": 88870580, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Very Small Pile of Gold 2 (Dif. 2)", + "id": 88870581, + "difficulty": 2, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Potion Pile (Dif. 2)", + "id": 88870582, + "difficulty": 2, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress - Key 5", + "id": 88870583, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 1 (Dif. 4)", + "id": 8887230, + "difficulty": 4, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Potion 1 (Dif. 4)", + "id": 8887231, + "difficulty": 4, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Fruit 1 (Dif. 3)", + "id": 8887232, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Timestop 1", + "id": 8887233, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Poison Fruit 1", + "id": 8887234, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Meat 1 (Dif. 2)", + "id": 8887235, + "difficulty": 2, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 2", + "id": 8887236, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Fire Shield 1 (Dif. 3)", + "id": 8887237, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Scroll 1", + "id": 8887238, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Levitate 1", + "id": 8887239, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Scroll 2", + "id": 88872310, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Scroll 3", + "id": 88872311, + "difficulty": 1, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Barrel - Meat 2", + "id": 88872312, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Invisibility 1 (Dif. 2)", + "id": 88872313, + "difficulty": 2, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Dark Chest - Random 1", + "id": 88872314, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 3", + "id": 88872315, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 4", + "id": 88872316, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 5", + "id": 88872317, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 6 (Dif. 4)", + "id": 88872318, + "difficulty": 4, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 7 (Dif. 3)", + "id": 88872319, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 8 (Dif. 3)", + "id": 88872320, + "difficulty": 3, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 9", + "id": 88872321, + "difficulty": 1, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 10", + "id": 88872322, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 11", + "id": 88872323, + "difficulty": 1, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 12", + "id": 88872324, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 13", + "id": 88872325, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 14 (Dif. 3)", + "id": 88872326, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Speed Boots 1 (Dif. 2)", + "id": 88872327, + "difficulty": 2, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Gold 1 (Dif. 3)", + "id": 88872328, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Fruit 2 (Dif. 4)", + "id": 88872329, + "difficulty": 4, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 15 (Dif. 2)", + "id": 88872330, + "difficulty": 2, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Chest - Gold 1 (Dif. 2)", + "id": 88872331, + "difficulty": 2, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Chest - Gold 2", + "id": 88872332, + "difficulty": 1, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Barrel - Fruit 3 (Dif. 2)", + "id": 88872333, + "difficulty": 2, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Chest - Light Amulet 1", + "id": 88872334, + "difficulty": 1, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Chest - Gold 3 (Dif. 4)", + "id": 88872335, + "difficulty": 4, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Gold 4 (Dif. 3)", + "id": 88872336, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Gold 5", + "id": 88872337, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Gold 6 (Dif. 2)", + "id": 88872338, + "difficulty": 2, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Gold 7 (Dif. 4)", + "id": 88872339, + "difficulty": 4, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Gold 8", + "id": 88872340, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Scroll 1", + "id": 88872341, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 16 (Dif. 4)", + "id": 88872342, + "difficulty": 4, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Death 1 (Dif. 3)", + "id": 88872343, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Gold 2", + "id": 88872344, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Reflective Shot 1 (Dif. 4)", + "id": 88872345, + "difficulty": 4, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Barrel - Gold 3 (Dif. 2)", + "id": 88872346, + "difficulty": 2, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Barrel - Fruit 4", + "id": 88872347, + "difficulty": 1, + "tags": [ + "infernal_fortress", + "no_obelisks" + ] + }, + { + "name": "Infernal Fortress Barrel - Potion 1 (Dif. 3)", + "id": 88872348, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Key 17", + "id": 88872349, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Death 2 (Dif. 2)", + "id": 88872350, + "difficulty": 2, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Barrel - Gold 4 (Dif. 3)", + "id": 88872351, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - 3-Way Shot 1", + "id": 88872352, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Potion 2", + "id": 88872353, + "difficulty": 1, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Infernal Fortress Chest - Meat 1 (Dif. 3)", + "id": 88872354, + "difficulty": 3, + "tags": [ + "infernal_fortress" + ] + }, + { + "name": "Gates of the Underworld - Potion Pile", + "id": 88870584, + "difficulty": 1, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Rapid Fire (Dif. 3)", + "id": 88870585, + "difficulty": 3, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Reflective Shield (Dif. 2)", + "id": 88870586, + "difficulty": 2, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Reflective Shot (Dif. 2)", + "id": 88870587, + "difficulty": 2, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Lightning Shield (Dif. 2)", + "id": 88870588, + "difficulty": 2, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Fire Shield (Dif. 3)", + "id": 88870589, + "difficulty": 3, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Acid Amulet (Dif. 4)", + "id": 88870590, + "difficulty": 4, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Light Amulet (Dif. 3)", + "id": 88870591, + "difficulty": 3, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Lightning Amulet (Dif. 2)", + "id": 88870592, + "difficulty": 2, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Fire Amulet", + "id": 88870593, + "difficulty": 1, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Growth", + "id": 88870594, + "difficulty": 1, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Fire Breath", + "id": 88870595, + "difficulty": 1, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Phoenix Familiar (Dif. 2)", + "id": 88870596, + "difficulty": 2, + "tags": [ + "gates_of_the_underworld", + "no_obelisks" + ] + }, + { + "name": "Gates of the Underworld - Invulnerability (Dif. 4)", + "id": 88870597, + "difficulty": 4, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Acid Breath (Dif. 3)", + "id": 88870598, + "difficulty": 3, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - 5-Way Shot", + "id": 88870599, + "difficulty": 1, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Thunder Hammer (Dif. 4)", + "id": 88870600, + "difficulty": 4, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Lightning Breath (Dif. 2)", + "id": 88870601, + "difficulty": 2, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Timestop", + "id": 88870602, + "difficulty": 1, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - 3-Way Shot (Dif. 4)", + "id": 88870603, + "difficulty": 4, + "tags": [ + "gates_of_the_underworld", + "no_obelisks" + ] + }, + { + "name": "Gates of the Underworld - Super Shot", + "id": 88870604, + "difficulty": 1, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Speed Boots (Dif. 3)", + "id": 88870605, + "difficulty": 3, + "tags": [ + "gates_of_the_underworld" + ] + }, + { + "name": "Gates of the Underworld - Shrink (Dif. 4)", + "id": 88870606, + "difficulty": 4, + "tags": [ + "gates_of_the_underworld" + ] + } +] \ No newline at end of file