From f9c8816c439b89b095c28f2f4a167f88a3304f7f Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:23:22 +0200 Subject: [PATCH 01/27] Update minecraft_es.md Updated spanish minecraft tutorial --- .../assets/tutorial/minecraft/minecraft_es.md | 170 +++++++++--------- 1 file changed, 89 insertions(+), 81 deletions(-) diff --git a/WebHostLib/static/assets/tutorial/minecraft/minecraft_es.md b/WebHostLib/static/assets/tutorial/minecraft/minecraft_es.md index a0e9d71c..15ae3bd5 100644 --- a/WebHostLib/static/assets/tutorial/minecraft/minecraft_es.md +++ b/WebHostLib/static/assets/tutorial/minecraft/minecraft_es.md @@ -1,52 +1,12 @@ # Guia instalación de Minecraft Randomizer +#Instalacion automatica para el huesped de partida +- descarga e instala [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) and activa el modulo `Minecraft Client` + ## Software Requerido -### Servidor -- [Minecraft Forge](https://files.minecraftforge.net/net/minecraftforge/forge/index_1.16.5.html) -- [Minecraft Archipelago Randomizer Mod](https://github.com/KonoTyran/Minecraft_AP_Randomizer/releases) - -### Jugadores - [Minecraft Java Edition](https://www.minecraft.net/en-us/store/minecraft-java-edition) -## Procedimiento de instalación - -### Instalación de servidor dedicado -Solo una persona ha de realizar este proceso y hospedar un servidor dedicado para que los demas jueguen conectandose a él. -1. Descarga el instalador de **Minecraft Forge** 1.16.15 desde el enlace proporcionado, siempre asegurandose de bajar la version mas reciente. - -2. Ejecuta el fichero `forge-1.16.5-xx.x.x-installer.jar` y elije **install server**. - - En esta pagina elegiras ademas donde instalar el servidor, importante recordar esta localización en el siguiente paso. - -3. Navega al directorio donde hayas instalado el servidor y abre `forge-1.16.5-xx.x.x.jar` - - La primera vez que lances el servidor se cerrara (o no aparecerá nada en absoluto), debería haber un fichero nuevo en el directorio llamado `eula.txt`, el cual que contiene un enlace al EULA de minecraft, cambia la linea a `eula=true` para aceptar el EULA y poder utilizar el software de servidor. - - Esto creara la estructura de directorios apropiada para el siguiente paso - -4. Coloca el fichero `aprandomizer-x.x.x.jar` del segundo enlace en el directorio `mods` - - Cuando se ejecute el servidor de nuevo, generara el directorio `APData` que se necesitara para jugar - -### Instalación basica para jugadores -- Compra e instala Minecraft a traves del tercer enlace. - **Y listo!**. - Los jugadores solo necesitan una version no modificada de Minecraft para jugar! - -### Instalación avanzada para jugadores -***Esto no es requerido para jugar a minecraft randomizado.*** -Sin embargo lo recomendamos porque hace la experiencia mas llevadera. - -#### Recomended Mods -- [JourneyMap](https://www.curseforge.com/minecraft/mc-mods/journeymap) (Minimap) - - -1. Instala y ejecuta Minecraft al menos una vez. -2. Ejecuta el fichero `forge-1.16.5-xx.x.x-installer.jar` y elige **install client**. - - Ejecuta Minecraft forge al menos una vez para generar los directorios necesarios para el siguiente paso. -3. Navega a la carpeta de instalación de Minecraft y colocal los mods que quieras en el directorio `mods` - - Los directorios por defecto de instalación son: - - Windows `%APPDATA%\.minecraft\mods` - - macOS `~/Library/Application Support/minecraft/mods` - - Linux `~/.minecraft/mods` - ## Configura tu fichero YAML ### Que es un fichero YAML y potque necesito uno? @@ -58,42 +18,71 @@ pueden tener diferentes opciones ### Where do I get a YAML file? Un fichero basico yaml para minecraft tendra este aspecto. ```yaml -# Usado para describir tu yaml. Util si tienes multiples ficheros -description: Template Name -# Tu nombre en el juego. Los espacios son reemplazados por guiones bajos, limitado a 16 caracteres -name: YourName +description: Basic Minecraft Yaml +# Tu nombre en el juego. Espacios seran sustituidos por guinoes bajos y +# hay un limite de 16 caracteres +name: TuNombre game: Minecraft -accessibility: locations -# Recomendado no activar esto ya que el pool de objetos de Minecraft es bastante escueto, ademas hay muchas maneras alternativas de obtener los objetivos de Minecraft. -progression_balancing: off -# Cuantos avances se necesitan para hacer aparecer el Ender Dragon y acabar el juego. few = 30, normal = 50 , many = 70 -advancement_goal: - few: 0 - normal: 1 - many: 0 -# Modifica el nivel de objetos lógicamente requeridos para explorar areas peligrosas y pelear contra jefes. -combat_difficulty: - easy: 0 - normal: 1 - hard: 0 -# Avances que sean tediosos o basados en suerte tendran simplemente experiencia o cosas no necesarias -include_hard_advancements: - on: 0 - off: 1 -# Los avances extremadamente difíciles no seran requeridos; esto afecta a How Did We Get Here? y Adventuring Time. -include_insane_advancements: - on: 0 - off: 1 -# Los avances posteriores a Ender Dragon no tendrán objetos necesarios para que otros jugadores en el caso de un MW acaben su partida. -include_postgame_advancements: - on: 0 - off: 1 -# Actualmente desactivado; permite la mezcla de pueblos, puestos, fortalezas, bastiones y cuidades. -shuffle_structures: - on: 0 - off: 1 -``` +# Opciones compartidas por todos los juegos: +accessibility: locations +progression_balancing: on +# Opciones Especficicas para Minecraft + +Minecraft: + # Numero de logros requeridos (87 max) para que aparezca el Ender Dragon y completar el juego. + advancement_goal: 50 + + # Numero de trozos de huevo de dragon a obtener (30 max) antes de que el Ender Dragon aparezca. + egg_shards_required: 10 + + # Numero de huevos disponibles en la partida (30 max). + egg_shards_available: 15 + + # Modifica el nivel de objetos logicamente requeridos para + # explorar areas peligrosas y luchar contra jefes. + combat_difficulty: + easy: 0 + normal: 1 + hard: 0 + + # Si off, los logros que dependan de suerte o sean tediosos tendran objetos de apoyo, no necesarios para completar el juego. + include_hard_advancements: + on: 0 + off: 1 + + # Si off, los logros muy dificiles tendran objetos de apoyo, no necesarios para completar el juego. + # Solo afecta a How Did We Get Here? and Adventuring Time. + include_insane_advancements: + on: 0 + off: 1 + + # Algunos logros requieren derrotar al Ender Dragon; + # Si esto se queda en off, dichos logros no tendran objetos necesarios. + include_postgame_advancements: + on: 0 + off: 1 + + # Permite el mezclado de villas, puesto, fortalezas, bastiones y ciudades de END. + shuffle_structures: + on: 0 + off: 1 + + # Añade brujulas de estructura al juego, + # apuntaran a la estructura correspondiente mas cercana. + structure_compasses: + on: 0 + off: 1 + + # Reemplaza un porcentaje de objetos innecesarios por trampas abeja + # las cuales crearan multiples abejas agresivas alrededor de los jugadores cuando se reciba. + bee_traps: + 0: 1 + 25: 0 + 50: 0 + 75: 0 + 100: 0 +``` ## Unirse a un juego MultiWorld @@ -104,18 +93,37 @@ Cuando te unes a un juego multiworld, se te pedirá que entregues tu fichero YAM Una vez la generación acabe, el anfitrión te dará un enlace a tu fichero de datos o un zip con los ficheros de todos. Tu fichero de datos tiene una extensión `.apmc`. -Pon tu fichero de datos en el directorio `APData` de tu forge server. Asegurate de eliminar los que hubiera anteriormente - +Haz doble click en tu fichero `.apmc` para que se arranque el cliente de minecraft y el servidor forge se ejecute. ### Conectar al multiserver Despues de poner tu fichero en el directorio `APData`, arranca el Forge server y asegurate que tienes el estado OP tecleando `/op TuUsuarioMinecraft` en la consola del servidor y entonces conectate con tu cliente Minecraft. -Una vez en juego introduce `/connect ()` donde `` es la dirección del servidor -Archipelago. `()` +Una vez en juego introduce `/connect (Port) ()` donde `` es la dirección del servidor. `(Port)` solo es requerido si el servidor Archipelago no esta usando el puerto por defecto 38281. +`()` solo se necesita si el servidor Archipleago tiene un password activo. + ### Jugar al juego Cuando la consola te diga que te has unido a la sala, estas lista/o para empezar a jugar. Felicidades por unirte exitosamente a un juego multiworld! Llegados a este punto cualquier jugador adicional puede conectarse a tu servidor forge. +## Procedimiento de instalación manual +Solo es requerido si quieres usar una instalacion de forge por ti mismo, recomendamos usar el instalador de Archipelago +###Software Requerido +- [Minecraft Forge](https://files.minecraftforge.net/net/minecraftforge/forge/index_1.16.5.html) +- [Minecraft Archipelago Randomizer Mod](https://github.com/KonoTyran/Minecraft_AP_Randomizer/releases) + +### Instalación de servidor dedicado +Solo una persona ha de realizar este proceso y hospedar un servidor dedicado para que los demas jueguen conectandose a él. +1. Descarga el instalador de **Minecraft Forge** 1.16.5 desde el enlace proporcionado, siempre asegurandose de bajar la version mas reciente. + +2. Ejecuta el fichero `forge-1.16.5-xx.x.x-installer.jar` y elije **install server**. + - En esta pagina elegiras ademas donde instalar el servidor, importante recordar esta localización en el siguiente paso. + +3. Navega al directorio donde hayas instalado el servidor y abre `forge-1.16.5-xx.x.x.jar` + - La primera vez que lances el servidor se cerrara (o no aparecerá nada en absoluto), debería haber un fichero nuevo en el directorio llamado `eula.txt`, el cual que contiene un enlace al EULA de minecraft, cambia la linea a `eula=true` para aceptar el EULA y poder utilizar el software de servidor. + - Esto creara la estructura de directorios apropiada para el siguiente paso + +4. Coloca el fichero `aprandomizer-x.x.x.jar` del segundo enlace en el directorio `mods` + - Cuando se ejecute el servidor de nuevo, generara el directorio `APData` que se necesitara para jugar From c0ff90fc8679b501d81e8aedc890ddbc5e2bced4 Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:29:43 +0200 Subject: [PATCH 02/27] Update minecraft_es.md Little warning added --- WebHostLib/static/assets/tutorial/minecraft/minecraft_es.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WebHostLib/static/assets/tutorial/minecraft/minecraft_es.md b/WebHostLib/static/assets/tutorial/minecraft/minecraft_es.md index 15ae3bd5..8cd35fba 100644 --- a/WebHostLib/static/assets/tutorial/minecraft/minecraft_es.md +++ b/WebHostLib/static/assets/tutorial/minecraft/minecraft_es.md @@ -113,6 +113,8 @@ Solo es requerido si quieres usar una instalacion de forge por ti mismo, recomen ###Software Requerido - [Minecraft Forge](https://files.minecraftforge.net/net/minecraftforge/forge/index_1.16.5.html) - [Minecraft Archipelago Randomizer Mod](https://github.com/KonoTyran/Minecraft_AP_Randomizer/releases) +**NO INSTALES ESTO EN TU CLIENTE MINECRAFT** + ### Instalación de servidor dedicado Solo una persona ha de realizar este proceso y hospedar un servidor dedicado para que los demas jueguen conectandose a él. From 89cbd05600b8361d095109641ca61e4b63f309ea Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Mon, 4 Oct 2021 21:45:54 +0200 Subject: [PATCH 03/27] OOT tutorials added --- .../assets/tutorial/zeldaOOT/zeldaOOT_en.md | 407 ++++++++++++++++++ .../assets/tutorial/zeldaOOT/zeldaOOT_es.md | 372 ++++++++++++++++ 2 files changed, 779 insertions(+) create mode 100644 WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md create mode 100644 WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md new file mode 100644 index 00000000..27a531a3 --- /dev/null +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md @@ -0,0 +1,407 @@ +# Setup Guide for Ocarina of time Archipelago + +## Important + +As we are using Z5Client and Bizhawk, this guide is only applicable to Windows. + +## Required Software Requerido + +- [bizhawk+script+Z5Client](https://github.com/ArchipelagoMW/Z5Client/releases) We recommend download Z5Client-setup as it makes some steps automatic. + +## Install Emulator and client + +Download getBizhawk.ps1 from previous link. Place it on the folder where you want your emulator to be installed, right click on it and select "Run with PowerShell". This will download all the needed dependencies used by the emulator. Can take a while. + +It's strongly recommended to associate N64 rom extension (\*.n64) to the Bizhawk we've just installed. To do so, we simple have to search any N64 we happened to own, right click and select "Open with...", we unfold the list that appears and select the bottom option "Look for another application", we browse to Bizhawk folder and select EmuHawk.exe + +Place the ootMulti.lua file from the previous link inside the "lua" folder from the just installed emulator. + +Install the Z5Client using its setup. + +## 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? + +A basic OOT yaml will look like this. (There are lots of cosmetic options that have been removed for the sake of this tutorial, if you want to see a complete list, download (Archipelago)[https://github.com/ArchipelagoMW/Archipelago/releases] and look for the sample file in the "Players" folder)) +```yaml +description: Default Ocarina of Time Template # Used to describe your yaml. Useful if you have multiple files +# Your name in-game. Spaces will be replaced with underscores and there is a 16 character limit +name: YourName{number} +#{player} will be replaced with the player's slot number. +#{PLAYER} will be replaced with the player's slot number if that slot number is greater than 1. +#{number} will be replaced with the counter value of the name. +#{NUMBER} will be replaced with the counter value of the name if the counter value is greater than 1. +game: + Ocarina of Time: 1 +requires: + version: 0.1.7 # Version of Archipelago required for this yaml to work as expected. +# Shared Options supported by all games: +accessibility: + items: 0 # Guarantees you will be able to acquire all items, but you may not be able to access all locations + locations: 50 # Guarantees you will be able to access all locations, and therefore all items + none: 0 # Guarantees only that the game is beatable. You may not be able to access all locations or acquire all items +progression_balancing: + on: 50 # A system to reduce BK, as in times during which you can't do anything by moving your items into an earlier access sphere to make it likely you have stuff to do + off: 0 # Turn this off if you don't mind a longer multiworld, or can glitch/sequence break around missing items. + # The following 4 options can be uncommented and moved into a game's section they should affect + # start_inventory: # Begin the file with the listed items/upgrades + # Please only use items for the correct game, use triggers if need to be have seperated lists. + # Pegasus Boots: on + # Bomb Upgrade (+10): 4 + # Arrow Upgrade (+10): 4 +# start_hints: # Begin the game with these items' locations revealed to you at the start of the game. Get the info via !hint in your client. +# - Moon Pearl +# local_items: # Force certain items to appear in your world only, not across the multiworld. Recognizes some group names, like "Swords" +# - "Moon Pearl" +# - "Small Keys" +# - "Big Keys" +# non_local_items: # Force certain items to appear outside your world only, unless in single-player. Recognizes some group names, like "Swords" +# - "Progressive Weapons" +# exclude_locations: # Force certain locations to never contain progression items, and always be filled with junk. +# - "Master Sword Pedestal" +Ocarina of Time: + logic_rules: # Set the logic used for the generator. + glitchless: 50 + glitched: 0 + no_logic: 0 + logic_no_night_tokens_without_suns_song: # Nighttime skulltulas will logically require Sun's Song. + false: 50 + true: 0 + open_forest: # Set the state of Kokiri Forest and the path to Deku Tree. + open: 50 + closed_deku: 0 + closed: 0 + open_kakariko: # Set the state of the Kakariko Village gate. + open: 50 + zelda: 0 + closed: 0 + open_door_of_time: # Open the Door of Time by default, without the Song of Time. + false: 0 + true: 50 + zora_fountain: # Set the state of King Zora, blocking the way to Zora's Fountain. + open: 0 + adult: 0 + closed: 50 + gerudo_fortress: # Set the requirements for access to Gerudo Fortress. + normal: 0 + fast: 50 + open: 0 + bridge: # Set the requirements for the Rainbow Bridge. + open: 0 + vanilla: 0 + stones: 0 + medallions: 50 + dungeons: 0 + tokens: 0 + trials: # Set the number of required trials in Ganon's Castle. + # you can add additional values between minimum and maximum + 0: 50 # minimum value + 6: 0 # maximum value + random: 0 + random-low: 0 + random-high: 0 + starting_age: # Choose which age Link will start as. + child: 50 + adult: 0 + triforce_hunt: # Gather pieces of the Triforce scattered around the world to complete the game. + false: 50 + true: 0 + triforce_goal: # Number of Triforce pieces required to complete the game. Total number placed determined by the Item Pool setting. + # you can add additional values between minimum and maximum + 1: 0 # minimum value + 50: 0 # maximum value + random: 0 + random-low: 0 + random-high: 0 + 20: 50 + bombchus_in_logic: # Bombchus are properly considered in logic. The first found pack will have 20 chus; Kokiri Shop and Bazaar sell refills; bombchus open Bombchu Bowling. + false: 50 + true: 0 + bridge_stones: # Set the number of Spiritual Stones required for the rainbow bridge. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 3: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + bridge_medallions: # Set the number of medallions required for the rainbow bridge. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 6: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + bridge_rewards: # Set the number of dungeon rewards required for the rainbow bridge. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 9: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + bridge_tokens: # Set the number of Gold Skulltula Tokens required for the rainbow bridge. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 100: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + shuffle_mapcompass: # Control where to shuffle dungeon maps and compasses. + remove: 0 + startwith: 50 + vanilla: 0 + dungeon: 0 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_smallkeys: # Control where to shuffle dungeon small keys. + remove: 0 + vanilla: 0 + dungeon: 50 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_fortresskeys: # Control where to shuffle the Gerudo Fortress small keys. + vanilla: 50 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_bosskeys: # Control where to shuffle boss keys, except the Ganon's Castle Boss Key. + remove: 0 + vanilla: 0 + dungeon: 50 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_ganon_bosskey: # Control where to shuffle the Ganon's Castle Boss Key. + remove: 50 + vanilla: 0 + dungeon: 0 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + on_lacs: 0 + enhance_map_compass: # Map tells if a dungeon is vanilla or MQ. Compass tells what the dungeon reward is. + false: 50 + true: 0 + lacs_condition: # Set the requirements for the Light Arrow Cutscene in the Temple of Time. + vanilla: 50 + stones: 0 + medallions: 0 + dungeons: 0 + tokens: 0 + lacs_stones: # Set the number of Spiritual Stones required for LACS. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 3: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + lacs_medallions: # Set the number of medallions required for LACS. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 6: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + lacs_rewards: # Set the number of dungeon rewards required for LACS. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 9: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + lacs_tokens: # Set the number of Gold Skulltula Tokens required for LACS. + # you can add additional values between minimum and maximum + 0: 0 # minimum value + 100: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + shuffle_song_items: # Set where songs can appear. + song: 50 + dungeon: 0 + any: 0 + shopsanity: # Randomizes shop contents. Set to "off" to not shuffle shops; "0" shuffles shops but does not allow multiworld items in shops. + 0: 0 + 1: 0 + 2: 0 + 3: 0 + 4: 0 + random_value: 0 + off: 50 + tokensanity: # Token rewards from Gold Skulltulas are shuffled into the pool. + off: 50 + dungeons: 0 + overworld: 0 + all: 0 + shuffle_scrubs: # Shuffle the items sold by Business Scrubs, and set the prices. + off: 50 + low: 0 + regular: 0 + random_prices: 0 + shuffle_cows: # Cows give items when Epona's Song is played. + false: 50 + true: 0 + shuffle_kokiri_sword: # Shuffle Kokiri Sword into the item pool. + false: 50 + true: 0 + shuffle_ocarinas: # Shuffle the Fairy Ocarina and Ocarina of Time into the item pool. + false: 50 + true: 0 + shuffle_weird_egg: # Shuffle the Weird Egg from Malon at Hyrule Castle. + false: 50 + true: 0 + shuffle_gerudo_card: # Shuffle the Gerudo Membership Card into the item pool. + false: 50 + true: 0 + shuffle_beans: # Adds a pack of 10 beans to the item pool and changes the bean salesman to sell one item for 60 rupees. + false: 50 + true: 0 + shuffle_medigoron_carpet_salesman: # Shuffle the items sold by Medigoron and the Haunted Wasteland Carpet Salesman. + false: 50 + true: 0 + skip_child_zelda: # Game starts with Zelda's Letter, the item at Zelda's Lullaby, and the relevant events already completed. + false: 50 + true: 0 + no_escape_sequence: # Skips the tower collapse sequence between the Ganondorf and Ganon fights. + false: 0 + true: 50 + no_guard_stealth: # The crawlspace into Hyrule Castle skips straight to Zelda. + false: 0 + true: 50 + no_epona_race: # Epona can always be summoned with Epona's Song. + false: 0 + true: 50 + skip_some_minigame_phases: # Dampe Race and Horseback Archery give both rewards if the second condition is met on the first attempt. + false: 0 + true: 50 + complete_mask_quest: # All masks are immediately available to borrow from the Happy Mask Shop. + false: 50 + true: 0 + useful_cutscenes: # Reenables the Poe cutscene in Forest Temple, Darunia in Fire Temple, and Twinrova introduction. Mostly useful for glitched. + false: 50 + true: 0 + fast_chests: # All chest animations are fast. If disabled, major items have a slow animation. + false: 0 + true: 50 + free_scarecrow: # Pulling out the ocarina near a scarecrow spot spawns Pierre without needing the song. + false: 50 + true: 0 + fast_bunny_hood: # Bunny Hood lets you move 1.5x faster like in Majora's Mask. + false: 50 + true: 0 + chicken_count: # Controls the number of Cuccos for Anju to give an item as child. + \# you can add additional values between minimum and maximum + 0: 0 # minimum value + 7: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + hints: # Gossip Stones can give hints about item locations. + none: 0 + mask: 0 + agony: 0 + always: 50 + hint_dist: # Choose the hint distribution to use. Affects the frequency of strong hints, which items are always hinted, etc. + balanced: 50 + ddr: 0 + league: 0 + mw2: 0 + scrubs: 0 + strong: 0 + tournament: 0 + useless: 0 + very_strong: 0 + text_shuffle: # Randomizes text in the game for comedic effect. + none: 50 + except_hints: 0 + complete: 0 + damage_multiplier: # Controls the amount of damage Link takes. + half: 0 + normal: 50 + double: 0 + quadruple: 0 + ohko: 0 + no_collectible_hearts: # Hearts will not drop from enemies or objects. + false: 50 + true: 0 + starting_tod: # Change the starting time of day. + default: 50 + sunrise: 0 + morning: 0 + noon: 0 + afternoon: 0 + sunset: 0 + evening: 0 + midnight: 0 + witching_hour: 0 + start_with_consumables: # Start the game with full Deku Sticks and Deku Nuts. + false: 50 + true: 0 + start_with_rupees: # Start with a full wallet. Wallet upgrades will also fill your wallet. + false: 50 + true: 0 + item_pool_value: # Changes the number of items available in the game. + plentiful: 0 + balanced: 50 + scarce: 0 + minimal: 0 + junk_ice_traps: # Adds ice traps to the item pool. + off: 0 + normal: 50 + on: 0 + mayhem: 0 + onslaught: 0 + ice_trap_appearance: # Changes the appearance of ice traps as freestanding items. + major_only: 50 + junk_only: 0 + anything: 0 + logic_earliest_adult_trade: # Earliest item that can appear in the adult trade sequence. + pocket_egg: 0 + pocket_cucco: 0 + cojiro: 0 + odd_mushroom: 0 + poachers_saw: 0 + broken_sword: 0 + prescription: 50 + eyeball_frog: 0 + eyedrops: 0 + claim_check: 0 + logic_latest_adult_trade: # Latest item that can appear in the adult trade sequence. + pocket_egg: 0 + pocket_cucco: 0 + cojiro: 0 + odd_mushroom: 0 + poachers_saw: 0 + broken_sword: 0 + prescription: 0 + eyeball_frog: 0 + eyedrops: 0 + claim_check: 50 + +``` + +## Joining a MultiWorld Game + +### Obtain your OOT patch file + +When you join a multiworld game, you will be asked to provide your YAML file to whoever is hosting. 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 `.z5ap` extension. + +Double click on your `.z5ap` file to start Z5Client and start the ROM patch process. Once the process is finished (this can take a while) emulator will be started automatically (If we associated the extension to the emulator like we already recommended) + +### Connect to multiserver +Once both Z5Client and emulator are started we must connect them, to do so we just simply click on the "Tools" menu and select "Lua console". On the new window, click on the folder icon and look for the ootMulti.lua file. Once the file is loaded it will conect automatically to Z5Client. + +Note: We strongly advise you don't open any emulator menu while it and Z5client are connected, as the script will halt and disconnects can happen. + +To connect the client to the multiserver simple put address:port on the textfield on top and press enter (if the server uses password, type on the bottom textfield /connect address:puerto contraseña, to connect) + +And you are ready to start your adventure in Hyrule. \ No newline at end of file diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md new file mode 100644 index 00000000..521a85ff --- /dev/null +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md @@ -0,0 +1,372 @@ +# Guia instalación de Ocarina of time Archipelago + +## Nota importante + +Al usar el cliente y bizhawk, esta guia solo es aplicable en Windows. + +## Software Requerido + +- [bizhawk+script+Z5Client](https://github.com/ArchipelagoMW/Z5Client/releases) Recomendamos bajar el setup de Z5client ya que automatizara varios pasos mas adelante + +## Instala emulador y cliente + +Descarga el fichero getBizhawk.ps1 del enlace anterior. Colocalo en la carpeta donde desees instalar el emulador, haz click derecho en él y selecciona "Ejecutar con PowerShell". Esto descargara todas las dependencias necesarias para el emulador. Puede tardar un rato. + +Es recomendable asociar la extensión de las roms de N64 (\*.n64) al bizhawk que hemos instalado anteriormente. Para hacerlo simplemente debemos buscar alguna rom de n64 que tengamos, hacer click derecho, hacer click en "Abrir con...", desplegar la lista y buscar la opcion "Buscar otra aplicacion", navegar hasta el directorio de bizhawk y seleccionar EmuHawk.exe + +Situa el fichero ootMulti.lua del enlace anterior en la carpeta "lua" del emulador recien instalado. + +Instala el cliente Z5Client. + +## Configura tu fichero YAML + +### Que es un fichero YAML y por qué necesito uno? +Tu fichero YAML contiene un numero de opciones que proveen al generador con informacion sobre como debe generar tu juego. +Cada jugador de un multiworld entregara u propio fichero YAML. +Esto permite que cada jugador disfrute de una experiencia personalizada a su gusto y diferentes jugadores dentro del mismo multiworld +pueden tener diferentes opciones + +### Where do I get a YAML file? +Un fichero basico yaml para OOT tendra este aspecto. (Hay muchas opciones cosméticas que se han ignorado para este tutorial, si quieres ver una lista completa, descarga (Archipelago)[https://github.com/ArchipelagoMW/Archipelago/releases] y buscar el fichero de ejemplo en el directorio "Players")) +```yaml +description: Default Ocarina of Time Template # Describe tu fichero yalm +\# Tu nombre en el juego. Los espacio seran reemplazados por _ y hay un limite de 16 caracteres +name: YourName{number} +game: + Ocarina of Time: 1 +requires: + version: 0.1.7 # Version de archipelago minima. +\# Opciones compartidas por todos los juegos: +accessibility: + items: 0 # Garantiza que puedes obtener todos los objetos pero no todas las localizaciones + locations: 50 # Garantiza que puedes obtener todas las localizaciones + none: 0 # Solo garantiza que el juego pueda completarse. +progression_balancing: + on: 50 # Un sistema para reducir tiempos de espera en una partida multiworld + off: 0 +Ocarina of Time: + logic_rules: # Logica usada por el randomizer. + glitchless: 50 + glitched: 0 + no_logic: 0 + logic_no_night_tokens_without_suns_song: # Las skulltulas nocturnas requeriran la cancion del sol por logica + false: 50 + true: 0 + open_forest: # Indica el estado del bosque Kokiri y el camino al Arbol Deku. + open: 50 + closed_deku: 0 + closed: 0 + open_kakariko: # Indica el estado de la puerta de Kakariko hacia la montaña de la muerte. + open: 50 + zelda: 0 + closed: 0 + open_door_of_time: # Abre la puerta del tiempo sin la cancion del tiempo. + false: 0 + true: 50 + zora_fountain: # Indica el estado del rey zora bloqueando el camino a la fuente Zora. + open: 0 + adult: 0 + closed: 50 + gerudo_fortress: # Indica los requerimientos para acceder a la fortaleza Gerudo. + normal: 0 + fast: 50 + open: 0 + bridge: # Indica los requerimientos para el puente arco iris. + open: 0 + vanilla: 0 + stones: 0 + medallions: 50 + dungeons: 0 + tokens: 0 + trials: # Numero de pruebas dentro del castillo de Ganon. + 0: 50 # minimum value + 6: 0 # maximum value + random: 0 + random-low: 0 + random-high: 0 + starting_age: # Indica la edad con la que empieza link. + child: 50 + adult: 0 + triforce_hunt: # Reune piezas de trifuerza para completar el juego. + false: 50 + true: 0 + triforce_goal: # Numero de piezas de trifuerza requeridas. El numero de piezas disponibles es determinado por la opcion "Item pool". + 1: 0 # minimum value + 50: 0 # maximum value + random: 0 + random-low: 0 + random-high: 0 + 20: 50 + bombchus_in_logic: # Los bombchus son considerados para la logica. El primer pack encontrado da 20 chus y las tiendas kokiri y el bazaar los venden. Bombchus abren la bolera. + false: 50 + true: 0 + bridge_stones: # Numero de piedras para abrir el puente arco iris. + 0: 0 # minimum value + 3: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + bridge_medallions: # Numero de medallones para abrir el puente arco iris. + 0: 0 # minimum value + 6: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + bridge_rewards: # Numero de mazmorras (cualquier combinacion de medallones y piedras) para abrir el puente arco iris. + 0: 0 # minimum value + 9: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + bridge_tokens: # Numero de skultullas de oro requeridas para el puente arco iris. + 0: 0 # minimum value + 100: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + shuffle_mapcompass: # Controla donde pueden aparecer los mapas y las brujulas. + remove: 0 + startwith: 50 + vanilla: 0 + dungeon: 0 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_smallkeys: # Controla donde pueden aparecer las llaves pequeñas. + remove: 0 + vanilla: 0 + dungeon: 50 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_fortresskeys: # Controla donde pueden aparecer las llaves de la fortaleza Gerudo. + vanilla: 50 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_bosskeys: # Controla donde pueden aparecer las llaves de jefe (excepto la llave del castillo de ganon). + remove: 0 + vanilla: 0 + dungeon: 50 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + shuffle_ganon_bosskey: # Controla donde puede aparecer la llave del jefe del castillo de Ganon. + remove: 50 + vanilla: 0 + dungeon: 0 + overworld: 0 + any_dungeon: 0 + keysanity: 0 + on_lacs: 0 + enhance_map_compass: # El mapa indica si una dungeon es clasica o Master Quest. Las brujulas indican la recompensa de mazmorra. + false: 50 + true: 0 + lacs_condition: # Marca el requerimiento para la escena de las flechas de luz (LACS) en el templo del tiempo. + vanilla: 50 + stones: 0 + medallions: 0 + dungeons: 0 + tokens: 0 + lacs_stones: # Marca el numero de piedras espirituales requeridas para LACS + 0: 0 # minimum value + 3: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + lacs_medallions: # Marca el numero de medallones requeridas para LACS. + 0: 0 # minimum value + 6: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + lacs_rewards: # Marca el numero de recompensas de mazmorra requeridas para LACS. + 0: 0 # minimum value + 9: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + lacs_tokens: # Marca el numero de Skulltulas de oro requeridas para LACS. + 0: 0 # minimum value + 100: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + shuffle_song_items: # Marca donde pueden aparecer las canciones. + song: 50 + dungeon: 0 + any: 0 + shopsanity: # Aleatoriza el contenido de las tiendas. "off" para no mezclar las tiendas; "0" mezcla las tiendas pero no permite objetos unicos en ellas. + 0: 0 + 1: 0 + 2: 0 + 3: 0 + 4: 0 + random_value: 0 + off: 50 + tokensanity: # Indica si las Skulltulas de oro pueden tener objetos que no sean su ficha. + off: 50 + dungeons: 0 + overworld: 0 + all: 0 + shuffle_scrubs: # Aleatoriza los objetos de los Scrubs vendedores y marca su precio. + off: 50 + low: 0 + regular: 0 + random_prices: 0 + shuffle_cows: # Las vacas dan objetos cuando les tocas las cancion de Epona. + false: 50 + true: 0 + shuffle_kokiri_sword: # Aleatoriza la posicion de la espada Kokiri. + false: 50 + true: 0 + shuffle_ocarinas: # Aleatoriza la posicion de las ocarinas. + false: 50 + true: 0 + shuffle_weird_egg: # Aleatoriza la posicion del huevo extraño. + false: 50 + true: 0 + shuffle_gerudo_card: # Aleatoriza la posicion de la tarjeta de membresia Gerudo. + false: 50 + true: 0 + shuffle_beans: # Añade un pack de 10 judias magicas al juego y el vendedor vende un solo objeto por 60 rupias. + false: 50 + true: 0 + shuffle_medigoron_carpet_salesman: # Aleatoriza el objeto que vende Medigoron y el vendedor de la alfombra voladora del paramo maldito. + false: 50 + true: 0 + skip_child_zelda: # Empieza el juego con la carta de zelda, el objeto que daria impa al enseñar la nana de zelda. Y zelda se considera ya visitada (puedes ir directamente a ver a Saria al bosque y a Malon al rancho) + false: 50 + true: 0 + no_escape_sequence: # Elimina la huida de link y zelda despues de ganar a Ganondorf. + false: 0 + true: 50 + no_guard_stealth: # Elimina la escena de sigilo antes de ver a Zelda. + false: 0 + true: 50 + no_epona_race: # No necesitas hacer la carrera para invocar a Epona. + false: 0 + true: 50 + skip_some_minigame_phases: # La carrera de Dampe y el minijuego de arco a caballo dan ambras recompensas a la vez si se cumplen las condiciones. + false: 0 + true: 50 + complete_mask_quest: # Todas las mascaras estan disponibles. + false: 50 + true: 0 + useful_cutscenes: # Ciertas escenas se mantienen (como los Poes del templo del bosque, Darunia o Twinrova. Principalmente util para modos con Glitches. + false: 50 + true: 0 + fast_chests: # Los cofres siempre se cogen rapido. Si se desactiva, los objetos importantes tienen animacion lenta. (IMPORTANTE: TODOS LOS OBJETOS QUE VAYAN A OTROS MUNDOS SE CONSIDERAN IMPORTANTES) + false: 0 + true: 50 + free_scarecrow: # Sacara la ocraina cerca de un punto con espantapajaros invoca a Pierre sin necesidad de la cancion. + false: 50 + true: 0 + fast_bunny_hood: # La capucha conejo mejora tu velocidad como en Majora's Mask. + false: 50 + true: 0 + chicken_count: # Numero de Cuccos que Anju necesita en el corral para que te de el objeto. + 0: 0 # minimum value + 7: 50 # maximum value + random: 0 + random-low: 0 + random-high: 0 + hints: # Marca el requerimiento para que las piedras chivatas den pistas. + none: 0 + mask: 0 + agony: 0 + always: 50 + hint_dist: # Elije la distribucion de pistas + balanced: 50 + ddr: 0 + league: 0 + mw2: 0 + scrubs: 0 + strong: 0 + tournament: 0 + useless: 0 + very_strong: 0 + damage_multiplier: # Controla el daño que recibe Link. + half: 0 + normal: 50 + double: 0 + quadruple: 0 + ohko: 0 + no_collectible_hearts: # No caen corazones de enemigos u objetos. + false: 50 + true: 0 + starting_tod: # Cambia el momento del dia al empezar el juego. + default: 50 + sunrise: 0 + morning: 0 + noon: 0 + afternoon: 0 + sunset: 0 + evening: 0 + midnight: 0 + witching_hour: 0 + start_with_consumables: # Empieza el juego con el maximo de palos y nueves Deku que pueda llevar Link. + false: 50 + true: 0 + start_with_rupees: # Empieza el juego con la cartera llena. Las mejoras de cartera vienen llenas. + false: 50 + true: 0 + item_pool_value: # Cambia el numero de objetos disponibles en el juego. + plentiful: 0 + balanced: 50 + scarce: 0 + minimal: 0 + junk_ice_traps: # Añade trampas de hielo. + off: 0 + normal: 50 + on: 0 + mayhem: 0 + onslaught: 0 + ice_trap_appearance: # Cambia la apariencia de las trampas de hielo cuando aparecen como objetos fuera de cofres. + major_only: 50 + junk_only: 0 + anything: 0 + logic_earliest_adult_trade: # Objeto mas bajo que puede aparecer en la secuencia de cambios de Link Adulto. + pocket_egg: 0 + pocket_cucco: 0 + cojiro: 0 + odd_mushroom: 0 + poachers_saw: 0 + broken_sword: 0 + prescription: 50 + eyeball_frog: 0 + eyedrops: 0 + claim_check: 0 + logic_latest_adult_trade: # Objeto mas tardio que puede aparecer en la secuencia de cambios de Link Adulto. + pocket_egg: 0 + pocket_cucco: 0 + cojiro: 0 + odd_mushroom: 0 + poachers_saw: 0 + broken_sword: 0 + prescription: 0 + eyeball_frog: 0 + eyedrops: 0 + claim_check: 50 + +``` + +## Unirse a un juego MultiWorld + +### Obten tu parche + + +Cuando te unes a un juego multiworld, se te pedirá que entregues tu fichero YAML a quien sea que hospede el juego multiworld. +Una vez la generación acabe, el anfitrión te dará un enlace a tu fichero de datos o un zip con los ficheros de todos. +Tu fichero de datos tiene una extensión `.z5ap`. + +Haz doble click en tu fichero `.z5ap` para que se arranque el Z5Client y realize el parcheado de la ROM. Una vez acabe el parcheado de la rom (esto puede llevar un tiempo) se abrira automaticamente el emulador (Si se ha asociado la extensión al emulador tal como hemos recomendado) + +### Conectar al multiserver +Una vez arrancado tanto el Z5Client como el emulador hay que conectarlo entre ellos, para ello simplemente accede al menu "Tools" y selecciona "Lua console". En la nueva ventana, dale al icono de la carpeta y busca el fichero ootMulti.lua. Al cargar dicho fichero se conectara automaticamente con el cliente. + +Nota: Es muy recomendable que no se abra ningun menu del emulador mientras esten emulador y Z5Client conectados, ya que el script de conexion se para en ese caso y pueden provocar desconexiones. + +Para conectar el cliente con el servidor simplemente pon la direccion_IP:puerto en la caja de texto de arriba y presiona enter (si el servidor tiene contraseña, en la caja de texto de abajo escribir /connect direccion:puerto contraseña, para conectar) + +Y ya estas listo, para emprender tu aventura por Hyrule. \ No newline at end of file From aa37c9bf81b089d1bb6a9498437c183acf7cf107 Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Mon, 4 Oct 2021 21:51:50 +0200 Subject: [PATCH 04/27] Update OOT tutorials Some typos, added how to solve disconnects. --- .../assets/tutorial/zeldaOOT/zeldaOOT_en.md | 28 +++---------------- .../assets/tutorial/zeldaOOT/zeldaOOT_es.md | 10 +++---- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md index 27a531a3..ee3fe7e5 100644 --- a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md @@ -32,11 +32,7 @@ A basic OOT yaml will look like this. (There are lots of cosmetic options that h ```yaml description: Default Ocarina of Time Template # Used to describe your yaml. Useful if you have multiple files # Your name in-game. Spaces will be replaced with underscores and there is a 16 character limit -name: YourName{number} -#{player} will be replaced with the player's slot number. -#{PLAYER} will be replaced with the player's slot number if that slot number is greater than 1. -#{number} will be replaced with the counter value of the name. -#{NUMBER} will be replaced with the counter value of the name if the counter value is greater than 1. +name: YourName game: Ocarina of Time: 1 requires: @@ -49,22 +45,6 @@ accessibility: progression_balancing: on: 50 # A system to reduce BK, as in times during which you can't do anything by moving your items into an earlier access sphere to make it likely you have stuff to do off: 0 # Turn this off if you don't mind a longer multiworld, or can glitch/sequence break around missing items. - # The following 4 options can be uncommented and moved into a game's section they should affect - # start_inventory: # Begin the file with the listed items/upgrades - # Please only use items for the correct game, use triggers if need to be have seperated lists. - # Pegasus Boots: on - # Bomb Upgrade (+10): 4 - # Arrow Upgrade (+10): 4 -# start_hints: # Begin the game with these items' locations revealed to you at the start of the game. Get the info via !hint in your client. -# - Moon Pearl -# local_items: # Force certain items to appear in your world only, not across the multiworld. Recognizes some group names, like "Swords" -# - "Moon Pearl" -# - "Small Keys" -# - "Big Keys" -# non_local_items: # Force certain items to appear outside your world only, unless in single-player. Recognizes some group names, like "Swords" -# - "Progressive Weapons" -# exclude_locations: # Force certain locations to never contain progression items, and always be filled with junk. -# - "Master Sword Pedestal" Ocarina of Time: logic_rules: # Set the logic used for the generator. glitchless: 50 @@ -395,13 +375,13 @@ When you join a multiworld game, you will be asked to provide your YAML file to 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 `.z5ap` extension. -Double click on your `.z5ap` file to start Z5Client and start the ROM patch process. Once the process is finished (this can take a while) emulator will be started automatically (If we associated the extension to the emulator like we already recommended) +Double click on your `.z5ap` file to start Z5Client and start the ROM patch process. Once the process is finished (this can take a while), emulator will be started automatically (If we associated the extension to the emulator like we already recommended) ### Connect to multiserver Once both Z5Client and emulator are started we must connect them, to do so we just simply click on the "Tools" menu and select "Lua console". On the new window, click on the folder icon and look for the ootMulti.lua file. Once the file is loaded it will conect automatically to Z5Client. -Note: We strongly advise you don't open any emulator menu while it and Z5client are connected, as the script will halt and disconnects can happen. +Note: We strongly advise you don't open any emulator menu while it and Z5client are connected, as the script will halt and disconnects can happen. If you get disconnected just double click on the script again. -To connect the client to the multiserver simple put address:port on the textfield on top and press enter (if the server uses password, type on the bottom textfield /connect address:puerto contraseña, to connect) +To connect the client to the multiserver simply put address:port on the textfield on top and press enter (if the server uses password, type on the bottom textfield /connect address:puerto contraseña, to connect) And you are ready to start your adventure in Hyrule. \ No newline at end of file diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md index 521a85ff..49109ced 100644 --- a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md @@ -10,9 +10,9 @@ Al usar el cliente y bizhawk, esta guia solo es aplicable en Windows. ## Instala emulador y cliente -Descarga el fichero getBizhawk.ps1 del enlace anterior. Colocalo en la carpeta donde desees instalar el emulador, haz click derecho en él y selecciona "Ejecutar con PowerShell". Esto descargara todas las dependencias necesarias para el emulador. Puede tardar un rato. +Descarga el fichero getBizhawk.ps1 del enlace anterior. Colocalo en la carpeta donde desees instalar el emulador, haz click derecho en él y selecciona "Ejecutar con PowerShell". Esto descargará todas las dependencias necesarias para el emulador. Puede tardar un rato. -Es recomendable asociar la extensión de las roms de N64 (\*.n64) al bizhawk que hemos instalado anteriormente. Para hacerlo simplemente debemos buscar alguna rom de n64 que tengamos, hacer click derecho, hacer click en "Abrir con...", desplegar la lista y buscar la opcion "Buscar otra aplicacion", navegar hasta el directorio de bizhawk y seleccionar EmuHawk.exe +Es recomendable asociar la extensión de las roms de N64 (\*.n64) al bizhawk que hemos instalado anteriormente. Para hacerlo simplemente debemos buscar alguna rom de n64 que tengamos, hacer click derecho, seleccionar "Abrir con...", desplegar la lista y buscar la opción "Buscar otra aplicación", navegar hasta el directorio de bizhawk y seleccionar EmuHawk.exe Situa el fichero ootMulti.lua del enlace anterior en la carpeta "lua" del emulador recien instalado. @@ -21,7 +21,7 @@ Instala el cliente Z5Client. ## Configura tu fichero YAML ### Que es un fichero YAML y por qué necesito uno? -Tu fichero YAML contiene un numero de opciones que proveen al generador con informacion sobre como debe generar tu juego. +Tu fichero YAML contiene un numero de opciones que proveen al generador con información sobre como debe generar tu juego. Cada jugador de un multiworld entregara u propio fichero YAML. Esto permite que cada jugador disfrute de una experiencia personalizada a su gusto y diferentes jugadores dentro del mismo multiworld pueden tener diferentes opciones @@ -363,9 +363,9 @@ Tu fichero de datos tiene una extensión `.z5ap`. Haz doble click en tu fichero `.z5ap` para que se arranque el Z5Client y realize el parcheado de la ROM. Una vez acabe el parcheado de la rom (esto puede llevar un tiempo) se abrira automaticamente el emulador (Si se ha asociado la extensión al emulador tal como hemos recomendado) ### Conectar al multiserver -Una vez arrancado tanto el Z5Client como el emulador hay que conectarlo entre ellos, para ello simplemente accede al menu "Tools" y selecciona "Lua console". En la nueva ventana, dale al icono de la carpeta y busca el fichero ootMulti.lua. Al cargar dicho fichero se conectara automaticamente con el cliente. +Una vez arrancado tanto el Z5Client como el emulador hay que conectarlo entre ellos, para ello simplemente accede al menú "Tools" y selecciona "Lua console". En la nueva ventana, dale al icono de la carpeta y busca el fichero ootMulti.lua. Al cargar dicho fichero se conectara automaticamente con el cliente. -Nota: Es muy recomendable que no se abra ningun menu del emulador mientras esten emulador y Z5Client conectados, ya que el script de conexion se para en ese caso y pueden provocar desconexiones. +Nota: Es muy recomendable que no se abra ningún menú del emulador mientras esten emulador y Z5Client conectados, ya que el script de conexión se para en ese caso y pueden provocar desconexiones. Si se pierde la conexion, simplemente haz doble click en el script de nuevo. Para conectar el cliente con el servidor simplemente pon la direccion_IP:puerto en la caja de texto de arriba y presiona enter (si el servidor tiene contraseña, en la caja de texto de abajo escribir /connect direccion:puerto contraseña, para conectar) From 8fc9a9c55e3fc8324efb6ec7b9157e22ba017187 Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Mon, 4 Oct 2021 22:44:09 +0200 Subject: [PATCH 05/27] Update WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md Co-authored-by: Hussein Farran --- WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md index ee3fe7e5..5891b5dc 100644 --- a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md @@ -4,7 +4,7 @@ As we are using Z5Client and Bizhawk, this guide is only applicable to Windows. -## Required Software Requerido +## Required Software - [bizhawk+script+Z5Client](https://github.com/ArchipelagoMW/Z5Client/releases) We recommend download Z5Client-setup as it makes some steps automatic. From f4a7777018a935b35d5cff71d68b2a356c2247f2 Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Mon, 4 Oct 2021 22:44:15 +0200 Subject: [PATCH 06/27] Update WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md Co-authored-by: Hussein Farran --- WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md index 5891b5dc..cbf26937 100644 --- a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md @@ -10,7 +10,7 @@ As we are using Z5Client and Bizhawk, this guide is only applicable to Windows. ## Install Emulator and client -Download getBizhawk.ps1 from previous link. Place it on the folder where you want your emulator to be installed, right click on it and select "Run with PowerShell". This will download all the needed dependencies used by the emulator. Can take a while. +Download getBizhawk.ps1 from previous link. Place it on the folder where you want your emulator to be installed, right click on it and select "Run with PowerShell". This will download all the needed dependencies used by the emulator. This can take a while. It's strongly recommended to associate N64 rom extension (\*.n64) to the Bizhawk we've just installed. To do so, we simple have to search any N64 we happened to own, right click and select "Open with...", we unfold the list that appears and select the bottom option "Look for another application", we browse to Bizhawk folder and select EmuHawk.exe From bddaa954abbcc340d237992ce6eff8e3aa04d512 Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Mon, 4 Oct 2021 22:44:37 +0200 Subject: [PATCH 07/27] Update WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md Co-authored-by: Hussein Farran --- WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md index cbf26937..cc0e0fac 100644 --- a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md @@ -384,4 +384,4 @@ Note: We strongly advise you don't open any emulator menu while it and Z5client To connect the client to the multiserver simply put address:port on the textfield on top and press enter (if the server uses password, type on the bottom textfield /connect address:puerto contraseña, to connect) -And you are ready to start your adventure in Hyrule. \ No newline at end of file +Now you are ready to start your adventure in Hyrule. \ No newline at end of file From 594183d7513f27a85b7b9f25db790207b35a11ad Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Mon, 4 Oct 2021 22:44:42 +0200 Subject: [PATCH 08/27] Update WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md Co-authored-by: Hussein Farran --- WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md index cc0e0fac..5f350716 100644 --- a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md @@ -382,6 +382,6 @@ Once both Z5Client and emulator are started we must connect them, to do so we ju Note: We strongly advise you don't open any emulator menu while it and Z5client are connected, as the script will halt and disconnects can happen. If you get disconnected just double click on the script again. -To connect the client to the multiserver simply put address:port on the textfield on top and press enter (if the server uses password, type on the bottom textfield /connect address:puerto contraseña, to connect) +To connect the client to the multiserver simply put address:port on the textfield on top and press enter (if the server uses password, type on the bottom textfield /connect
: [password], to connect) Now you are ready to start your adventure in Hyrule. \ No newline at end of file From d831923a541ed45d87af5683e8324f4ed0dabfb4 Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Mon, 4 Oct 2021 22:44:52 +0200 Subject: [PATCH 09/27] Update WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md Co-authored-by: Hussein Farran --- WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md index 5f350716..b4aa9df8 100644 --- a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md @@ -378,7 +378,7 @@ everyone's data files. Your data file should have a `.z5ap` extension. Double click on your `.z5ap` file to start Z5Client and start the ROM patch process. Once the process is finished (this can take a while), emulator will be started automatically (If we associated the extension to the emulator like we already recommended) ### Connect to multiserver -Once both Z5Client and emulator are started we must connect them, to do so we just simply click on the "Tools" menu and select "Lua console". On the new window, click on the folder icon and look for the ootMulti.lua file. Once the file is loaded it will conect automatically to Z5Client. +Once both the Z5Client and the emulator are started we must connect them. Within the emulator we click on the "Tools" menu and select "Lua console". In the new window click on the folder icon and look for the ootMulti.lua file. Once the file is loaded it will connect automatically to Z5Client. Note: We strongly advise you don't open any emulator menu while it and Z5client are connected, as the script will halt and disconnects can happen. If you get disconnected just double click on the script again. From df2d4a557eae892ff291fc7792428949db2eb1e8 Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Mon, 4 Oct 2021 22:45:03 +0200 Subject: [PATCH 10/27] Update WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md Co-authored-by: Hussein Farran --- WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md index b4aa9df8..e1f51d91 100644 --- a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md @@ -375,7 +375,7 @@ When you join a multiworld game, you will be asked to provide your YAML file to 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 `.z5ap` extension. -Double click on your `.z5ap` file to start Z5Client and start the ROM patch process. Once the process is finished (this can take a while), emulator will be started automatically (If we associated the extension to the emulator like we already recommended) +Double click on your `.z5ap` file to start Z5Client and start the ROM patch process. Once the process is finished (this can take a while), the emulator will be started automatically (If we associated the extension to the emulator as recommended) ### Connect to multiserver Once both the Z5Client and the emulator are started we must connect them. Within the emulator we click on the "Tools" menu and select "Lua console". In the new window click on the folder icon and look for the ootMulti.lua file. Once the file is loaded it will connect automatically to Z5Client. From ff4a9d17612a661ffe13a6c634cfca8453aaf7f7 Mon Sep 17 00:00:00 2001 From: Edos512 <30857677+Edos512@users.noreply.github.com> Date: Mon, 4 Oct 2021 22:45:10 +0200 Subject: [PATCH 11/27] Update WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md Co-authored-by: Hussein Farran --- WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md index e1f51d91..747d2e21 100644 --- a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md +++ b/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md @@ -12,7 +12,7 @@ As we are using Z5Client and Bizhawk, this guide is only applicable to Windows. Download getBizhawk.ps1 from previous link. Place it on the folder where you want your emulator to be installed, right click on it and select "Run with PowerShell". This will download all the needed dependencies used by the emulator. This can take a while. -It's strongly recommended to associate N64 rom extension (\*.n64) to the Bizhawk we've just installed. To do so, we simple have to search any N64 we happened to own, right click and select "Open with...", we unfold the list that appears and select the bottom option "Look for another application", we browse to Bizhawk folder and select EmuHawk.exe +It is strongly recommended to associate N64 rom extension (\*.n64) to the Bizhawk we've just installed. To do so, we simple have to search any N64 rom we happened to own, right click and select "Open with...", we unfold the list that appears and select the bottom option "Look for another application", we browse to Bizhawk folder and select EmuHawk.exe Place the ootMulti.lua file from the previous link inside the "lua" folder from the just installed emulator. From 3314ad0315b22c744b88b00b34f11feac475905a Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Mon, 4 Oct 2021 17:38:29 -0400 Subject: [PATCH 12/27] Update setup_en.md --- WebHostLib/static/assets/tutorial/archipelago/setup_en.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/tutorial/archipelago/setup_en.md b/WebHostLib/static/assets/tutorial/archipelago/setup_en.md index 332ca753..2279b8d4 100644 --- a/WebHostLib/static/assets/tutorial/archipelago/setup_en.md +++ b/WebHostLib/static/assets/tutorial/archipelago/setup_en.md @@ -7,6 +7,7 @@ Run the exe file, and after accepting the license agreement you will be prompted ## Generating a game ### Gather all player YAMLS All players that wish to play in the generated multiworld must have a YAML file which contains all of the settings that they wish to play with. +A YAML is a file which contains human readable markup. In other words, this is a settings file kind of like an INI file or a TOML file. Each player can go to the game's player settings page in order to determine the settings how they want them and then download a YAML file containing these settings. After getting all of the YAML files these can all either be placed together in the `Archipelago\Players` folder or compressed into a ZIP folder to then be uploaded to the [website generator](http://archipelago.gg:48484/generate). If rolling locally ensure that the folder is clear of any files you do not wish to include in the game such as the included default player settings files. @@ -23,4 +24,4 @@ The easiest and most recommended method is to upload the zip file that you gener ### Hosting a seed locally For this we'll assume you have already port forwarding `38281` and have generated a seed that is still in the `outputs` folder. Next, you'll want to run `ArchipelagoServer.exe`. A window will open in order to open the multiworld data for the game. You can either use the generated zip folder or extract the .archipelago file and use it. If everything worked correctly the console window should tell you it's now hosting a game with the IP, port, and password that clients will need in order to connect. -Extract the patch and mod files then send those to your friends and you're done! \ No newline at end of file +Extract the patch and mod files then send those to your friends and you're done! From 50f7541ef7435582e507eb2aec1dfd0d900d753a Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Mon, 4 Oct 2021 18:30:38 -0400 Subject: [PATCH 13/27] Update tutorial listing for z5 --- .../static/assets/tutorial/tutorials.json | 27 +++++++++++++++++++ .../zeldaOOT_en.md => zelda5/setup_en.md} | 0 .../zeldaOOT_es.md => zelda5/setup_es.md} | 0 3 files changed, 27 insertions(+) rename WebHostLib/static/assets/tutorial/{zeldaOOT/zeldaOOT_en.md => zelda5/setup_en.md} (100%) rename WebHostLib/static/assets/tutorial/{zeldaOOT/zeldaOOT_es.md => zelda5/setup_es.md} (100%) diff --git a/WebHostLib/static/assets/tutorial/tutorials.json b/WebHostLib/static/assets/tutorial/tutorials.json index 35fc9ecb..6d60f141 100644 --- a/WebHostLib/static/assets/tutorial/tutorials.json +++ b/WebHostLib/static/assets/tutorial/tutorials.json @@ -105,6 +105,33 @@ } ] }, + { + "gameTitle": "The Legend of Zelda: Ocarina of Time", + "tutorials": [ + { + "name": "Multiworld Setup Tutorial", + "description": "A guide to setting up the Archipelago Ocarina of Time software on your computer.", + "files": [ + { + "language": "English", + "filename": "zelda5/setup_en.md", + "link": "zelda5/setup/en", + "authors": [ + "Edos" + ] + }, + { + "language": "Spanish", + "filename": "zelda5/setup_es.md", + "link": "zelda5/setup/es", + "authors": [ + "Edos" + ] + } + ] + } + ] + }, { "gameTitle": "Factorio", "tutorials": [ diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md b/WebHostLib/static/assets/tutorial/zelda5/setup_en.md similarity index 100% rename from WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_en.md rename to WebHostLib/static/assets/tutorial/zelda5/setup_en.md diff --git a/WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md b/WebHostLib/static/assets/tutorial/zelda5/setup_es.md similarity index 100% rename from WebHostLib/static/assets/tutorial/zeldaOOT/zeldaOOT_es.md rename to WebHostLib/static/assets/tutorial/zelda5/setup_es.md From 50ba9a56f73aa420e9952068d5d7e82d75c09bef Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Mon, 4 Oct 2021 22:28:40 -0500 Subject: [PATCH 14/27] Risk of Rain 2: logic updates --- worlds/ror2/Items.py | 31 ++++++++++++++++++++++--------- worlds/ror2/Options.py | 4 +++- worlds/ror2/Rules.py | 4 +++- worlds/ror2/__init__.py | 11 ++++++----- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/worlds/ror2/Items.py b/worlds/ror2/Items.py index fa6f4d27..c4ece1dc 100644 --- a/worlds/ror2/Items.py +++ b/worlds/ror2/Items.py @@ -1,6 +1,5 @@ from BaseClasses import Item import typing -from random import randint class RiskOfRainItem(Item): game: str = "Risk of Rain 2" @@ -48,12 +47,12 @@ new_weights = { "Uncommon Item": 40, "Legendary Item": 10, "Boss Item": 5, - "Lunar Item": 15, - "Equipment": 25 + "Lunar Item": 10, + "Equipment": 20 } uncommon_weights = { - "Item Scrap, Green": 15, + "Item Scrap, Green": 45, "Item Scrap, Red": 5, "Item Scrap, Yellow": 1, "Item Scrap, White": 30, @@ -62,7 +61,7 @@ uncommon_weights = { "Legendary Item": 10, "Boss Item": 5, "Lunar Item": 15, - "Equipment": 25 + "Equipment": 20 } legendary_weights = { @@ -75,7 +74,7 @@ legendary_weights = { "Legendary Item": 100, "Boss Item": 5, "Lunar Item": 15, - "Equipment": 25 + "Equipment": 20 } lunartic_weights = { @@ -96,8 +95,8 @@ no_scraps_weights = { "Item Scrap, Red": 0, "Item Scrap, Yellow": 0, "Item Scrap, White": 0, - "Common Item": 80, - "Uncommon Item": 30, + "Common Item": 100, + "Uncommon Item": 40, "Legendary Item": 15, "Boss Item": 5, "Lunar Item": 10, @@ -117,6 +116,19 @@ even_weights = { "Equipment": 1 } +scraps_only = { + "Item Scrap, Green": 70, + "Item Scrap, White": 100, + "Item Scrap, Red": 30, + "Item Scrap, Yellow": 5, + "Common Item": 0, + "Uncommon Item": 0, + "Legendary Item": 0, + "Boss Item": 0, + "Lunar Item": 0, + "Equipment": 0 +} + item_pool_weights: typing.Dict[int, typing.Dict[str, int]] = { 0: default_weights, 1: new_weights, @@ -124,7 +136,8 @@ item_pool_weights: typing.Dict[int, typing.Dict[str, int]] = { 3: legendary_weights, 4: lunartic_weights, 6: no_scraps_weights, - 7: even_weights + 7: even_weights, + 8: scraps_only } lookup_id_to_name: typing.Dict[int, str] = {id: name for name, id in item_table.items() if id} diff --git a/worlds/ror2/Options.py b/worlds/ror2/Options.py index b2cc89a1..233d97f8 100644 --- a/worlds/ror2/Options.py +++ b/worlds/ror2/Options.py @@ -130,7 +130,8 @@ class ItemWeights(Choice): Lunartic makes everything a lunar item.
Chaos generates the pool completely at random with rarer items having a slight cap to prevent this option being too easy.
No Scraps removes all scrap items from the item pool.
- Even generates the item pool with every item having an even weight.""" + Even generates the item pool with every item having an even weight.
+ Scraps Only will be only scrap items in the item pool.""" displayname = "Item Weights" option_default = 0 option_new = 1 @@ -140,6 +141,7 @@ class ItemWeights(Choice): option_chaos = 5 option_no_scraps = 6 option_even = 7 + option_scraps_only = 8 #define a dictionary for the weights of the generated item pool. ror2_weights: typing.Dict[str, type(Option)] = { diff --git a/worlds/ror2/Rules.py b/worlds/ror2/Rules.py index 4f374832..9b33328f 100644 --- a/worlds/ror2/Rules.py +++ b/worlds/ror2/Rules.py @@ -8,7 +8,9 @@ class RiskOfRainLogic(LogicMixin): count: int = self.item_count("Common Item", player) + self.item_count("Uncommon Item", player) + \ self.item_count("Legendary Item", player) + self.item_count("Boss Item", player) + \ self.item_count("Lunar Item", player) + self.item_count("Equipment", player) + \ - self.item_count("Dio's Best Friend", player) + self.item_count("Dio's Best Friend", player) + self.item_count("Item Scrap, White", player) + \ + self.item_count("Item Scrap, Green", player) + self.item_count("Item Scrap, Red", player) + \ + self.item_count("Item Scrap, Yellow", player) return count >= amount diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index 166e58b7..4aa6f278 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -38,13 +38,13 @@ class RiskOfRainWorld(World): if pool_option == 5: junk_pool = { "Item Scrap, Green": self.world.random.randint(0, 80), - "Item Scrap, Red": self.world.random.randint(0, 40), - "Item Scrap, Yellow": self.world.random.randint(0, 50), + "Item Scrap, Red": self.world.random.randint(0, 45), + "Item Scrap, Yellow": self.world.random.randint(0, 30), "Item Scrap, White": self.world.random.randint(0, 100), "Common Item": self.world.random.randint(0, 100), "Uncommon Item": self.world.random.randint(0, 70), - "Legendary Item": self.world.random.randint(0, 45), - "Boss Item": self.world.random.randint(0, 30), + "Legendary Item": self.world.random.randint(0, 300), + "Boss Item": self.world.random.randint(0, 20), "Lunar Item": self.world.random.randint(0, 60), "Equipment": self.world.random.randint(0, 40) } @@ -65,7 +65,8 @@ class RiskOfRainWorld(World): } if not self.world.enable_lunar[self.player]: - junk_pool.pop("Lunar Item") + if not pool_option == 4: + junk_pool.pop("Lunar Item") # Generate item pool itempool = [] From 6ade8320296480cc6852917ba7c21a4e3c1b00af Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 5 Oct 2021 23:07:03 +0200 Subject: [PATCH 15/27] Subnautica: fix Aurora Prawn Suit Bay requires laser cutter Subnautica: add Dunes North Wreck's PDA to the correct wreck Subnautica: fix typo in Yellow Subnautica: fix progression tag for many items Subnautica: move extra items from valuable item pool to fast-fill Testclient at https://cdn.discordapp.com/attachments/731214280439103580/895047705552904222/ArchipelagoSubnautica.zip --- worlds/subnautica/Rules.py | 24 +++++------ worlds/subnautica/__init__.py | 14 ++++++- worlds/subnautica/items.json | 68 ++++++++++++++++---------------- worlds/subnautica/locations.json | 6 +-- 4 files changed, 61 insertions(+), 51 deletions(-) diff --git a/worlds/subnautica/Rules.py b/worlds/subnautica/Rules.py index a19c42df..8d5bcae4 100644 --- a/worlds/subnautica/Rules.py +++ b/worlds/subnautica/Rules.py @@ -106,7 +106,7 @@ def has_propulsion_cannon(state, player): return state.has("Propulsion Cannon Fragment", player, 2) or \ (has_prawn(state, player) and has_praw_propulsion_arm(state, player)) - + def has_cyclops_shield(state, player): return has_cyclops(state, player) and \ state.has("Cyclops Shield Generator", player) @@ -121,12 +121,12 @@ def has_cyclops_shield(state, player): # Fins are not used when using seaglide # def get_max_swim_depth(state, player): - #TODO, Make this a difficulty setting. + # TODO, Make this a difficulty setting. # Only go up to 200m without any submarines for now. return 200 # Rules bellow, are what are technically possible - + # has_ultra_high_capacity_tank = state.has("Ultra High Capacity Tank", player) # has_ultra_glide_fins = state.has("Ultra Glide Fins", player) @@ -151,7 +151,7 @@ def get_seamoth_max_depth(state, player): if has_seamoth(state, player): if has_seamoth_depth_module_mk3(state, player): return 900 - elif has_seamoth_depth_module_mk2(state, player): # Will never be the case, 3 is craftable + elif has_seamoth_depth_module_mk2(state, player): # Will never be the case, 3 is craftable return 500 elif has_seamoth_depth_module_mk1(state, player): return 300 @@ -165,7 +165,7 @@ def get_cyclops_max_depth(state, player): if has_cyclops(state, player): if has_cyclops_depth_module_mk3(state, player): return 1700 - elif has_cyclops_depth_module_mk2(state, player): # Will never be the case, 3 is craftable + elif has_cyclops_depth_module_mk2(state, player): # Will never be the case, 3 is craftable return 1300 elif has_cyclops_depth_module_mk1(state, player): return 900 @@ -188,12 +188,12 @@ def get_prawn_max_depth(state, player): def get_max_depth(state, player): - #TODO, Difficulty option, we can add vehicle depth + swim depth + # TODO, Difficulty option, we can add vehicle depth + swim depth # But at this point, we have to consider traver distance in caves, not # just depth - return max(get_max_swim_depth(state, player), \ - get_seamoth_max_depth(state, player), \ - get_cyclops_max_depth(state, player), \ + return max(get_max_swim_depth(state, player), + get_seamoth_max_depth(state, player), + get_cyclops_max_depth(state, player), get_prawn_max_depth(state, player)) @@ -201,9 +201,9 @@ def can_access_location(state, player, loc): pos_x = loc.get("position").get("x") pos_y = loc.get("position").get("y") pos_z = loc.get("position").get("z") - depth = -pos_y # y-up - map_center_dist = math.sqrt(pos_x**2 + pos_z**2) - aurora_dist = math.sqrt((pos_x - 1038.0)**2 + (pos_y - -3.4)**2 + (pos_z - -163.1)**2) + depth = -pos_y # y-up + map_center_dist = math.sqrt(pos_x ** 2 + pos_z ** 2) + aurora_dist = math.sqrt((pos_x - 1038.0) ** 2 + (pos_y - -3.4) ** 2 + (pos_z - -163.1) ** 2) need_radiation_suit = aurora_dist < 950 need_laser_cutter = loc.get("need_laser_cutter", False) diff --git a/worlds/subnautica/__init__.py b/worlds/subnautica/__init__.py index 5ccac126..0a3c9c2e 100644 --- a/worlds/subnautica/__init__.py +++ b/worlds/subnautica/__init__.py @@ -1,4 +1,5 @@ import logging +import typing logger = logging.getLogger("Subnautica") @@ -26,6 +27,8 @@ class SubnauticaWorld(World): location_name_to_id = locations_lookup_name_to_id options = options + data_version = 2 + def generate_basic(self): # Link regions self.world.get_entrance('Lifepod 5', self.player).connect(self.world.get_region('Planet 4546B', self.player)) @@ -34,19 +37,23 @@ class SubnauticaWorld(World): pool = [] neptune_launch_platform = None extras = 0 + valuable = self.world.item_pool[self.player] == "valuable" for item in item_table: for i in range(item["count"]): subnautica_item = self.create_item(item["name"]) if item["name"] == "Neptune Launch Platform": neptune_launch_platform = subnautica_item - elif not item["progression"] and self.world.item_pool[self.player] == "valuable": + elif valuable and not item["progression"]: self.world.push_precollected(subnautica_item) extras += 1 else: pool.append(subnautica_item) + for item_name in self.world.random.choices(sorted(advancement_item_names - {"Neptune Launch Platform"}), k=extras): - pool.append(self.create_item(item_name)) + item = self.create_item(item_name) + item.advancement = False # as it's an extra, just fast-fill it somewhere + pool.append(item) self.world.itempool += pool @@ -70,6 +77,9 @@ class SubnauticaWorld(World): item = lookup_name_to_item[name] return SubnauticaItem(name, item["progression"], item["id"], player=self.player) + def get_required_client_version(self) -> typing.Tuple[int, int, int]: + return max((0, 1, 9), super(SubnauticaWorld, self).get_required_client_version()) + def create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): ret = Region(name, None, name, player) diff --git a/worlds/subnautica/items.json b/worlds/subnautica/items.json index c5b08445..2dc4b225 100644 --- a/worlds/subnautica/items.json +++ b/worlds/subnautica/items.json @@ -1,60 +1,60 @@ [ - { "id": 35000, "count": 1, "progression": true, "tech_type": "Compass", "name": "Subnautica Compass" }, + { "id": 35000, "count": 1, "progression": false, "tech_type": "Compass", "name": "Compass" }, { "id": 35001, "count": 1, "progression": true, "tech_type": "PlasteelTank", "name": "Lightweight High Capacity Tank" }, { "id": 35002, "count": 1, "progression": true, "tech_type": "BaseUpgradeConsole", "name": "Vehicle Upgrade Console" }, { "id": 35003, "count": 1, "progression": true, "tech_type": "UltraGlideFins", "name": "Ultra Glide Fins" }, - { "id": 35004, "count": 1, "progression": true, "tech_type": "CyclopsSonarModule", "name": "Cyclops Sonar Upgrade" }, - { "id": 35005, "count": 1, "progression": true, "tech_type": "ReinforcedDiveSuit", "name": "Reinforced Dive Suit" }, - { "id": 35006, "count": 1, "progression": true, "tech_type": "CyclopsThermalReactorModule", "name": "Cyclops Thermal Reactor Module" }, - { "id": 35007, "count": 1, "progression": true, "tech_type": "Stillsuit", "name": "Stillsuit" }, + { "id": 35004, "count": 1, "progression": false, "tech_type": "CyclopsSonarModule", "name": "Cyclops Sonar Upgrade" }, + { "id": 35005, "count": 1, "progression": false, "tech_type": "ReinforcedDiveSuit", "name": "Reinforced Dive Suit" }, + { "id": 35006, "count": 1, "progression": false, "tech_type": "CyclopsThermalReactorModule", "name": "Cyclops Thermal Reactor Module" }, + { "id": 35007, "count": 1, "progression": false, "tech_type": "Stillsuit", "name": "Stillsuit" }, { "id": 35008, "count": 2, "progression": false, "tech_type": "BaseWaterParkFragment", "name": "Alien Containment Fragment" }, - { "id": 35009, "count": 1, "progression": true, "tech_type": "CyclopsDecoy", "name": "Creature Decoy" }, - { "id": 35010, "count": 1, "progression": true, "tech_type": "CyclopsFireSuppressionModule", "name": "Cyclops Fire Suppression System" }, - { "id": 35011, "count": 1, "progression": true, "tech_type": "SwimChargeFins", "name": "Swim Charge Fins" }, - { "id": 35012, "count": 1, "progression": true, "tech_type": "RepulsionCannon", "name": "Repulsion Cannon" }, - { "id": 35013, "count": 1, "progression": true, "tech_type": "CyclopsDecoyModule", "name": "Cyclops Decoy Tube Upgrade" }, + { "id": 35009, "count": 1, "progression": false, "tech_type": "CyclopsDecoy", "name": "Creature Decoy" }, + { "id": 35010, "count": 1, "progression": false, "tech_type": "CyclopsFireSuppressionModule", "name": "Cyclops Fire Suppression System" }, + { "id": 35011, "count": 1, "progression": false, "tech_type": "SwimChargeFins", "name": "Swim Charge Fins" }, + { "id": 35012, "count": 1, "progression": false, "tech_type": "RepulsionCannon", "name": "Repulsion Cannon" }, + { "id": 35013, "count": 1, "progression": false, "tech_type": "CyclopsDecoyModule", "name": "Cyclops Decoy Tube Upgrade" }, { "id": 35014, "count": 1, "progression": true, "tech_type": "CyclopsShieldModule", "name": "Cyclops Shield Generator" }, { "id": 35015, "count": 1, "progression": true, "tech_type": "CyclopsHullModule1", "name": "Cyclops Depth Module MK1" }, - { "id": 35016, "count": 1, "progression": true, "tech_type": "CyclopsSeamothRepairModule", "name": "Cyclops Docking Bay Repair Module" }, - { "id": 35017, "count": 2, "progression": true, "tech_type": "BatteryChargerFragment", "name": "Battery Charger fragment" }, - { "id": 35018, "count": 2, "progression": true, "tech_type": "BeaconFragment", "name": "Beacon Fragment" }, - { "id": 35019, "count": 2, "progression": true, "tech_type": "BaseBioReactorFragment", "name": "Bioreactor Fragment" }, + { "id": 35016, "count": 1, "progression": false, "tech_type": "CyclopsSeamothRepairModule", "name": "Cyclops Docking Bay Repair Module" }, + { "id": 35017, "count": 2, "progression": false, "tech_type": "BatteryChargerFragment", "name": "Battery Charger fragment" }, + { "id": 35018, "count": 2, "progression": false, "tech_type": "BeaconFragment", "name": "Beacon Fragment" }, + { "id": 35019, "count": 2, "progression": false, "tech_type": "BaseBioReactorFragment", "name": "Bioreactor Fragment" }, { "id": 35020, "count": 3, "progression": true, "tech_type": "CyclopsBridgeFragment", "name": "Cyclops Bridge Fragment" }, { "id": 35021, "count": 3, "progression": true, "tech_type": "CyclopsEngineFragment", "name": "Cyclops Engine Fragment" }, { "id": 35022, "count": 3, "progression": true, "tech_type": "CyclopsHullFragment", "name": "Cyclops Hull Fragment" }, - { "id": 35023, "count": 2, "progression": true, "tech_type": "GravSphereFragment", "name": "Grav Trap Fragment" }, + { "id": 35023, "count": 2, "progression": false, "tech_type": "GravSphereFragment", "name": "Grav Trap Fragment" }, { "id": 35024, "count": 3, "progression": true, "tech_type": "LaserCutterFragment", "name": "Laser Cutter Fragment" }, { "id": 35025, "count": 1, "progression": false, "tech_type": "TechlightFragment", "name": "Light Stick Fragment" }, { "id": 35026, "count": 3, "progression": true, "tech_type": "ConstructorFragment", "name": "Mobile Vehicle Bay Fragment" }, { "id": 35027, "count": 3, "progression": true, "tech_type": "WorkbenchFragment", "name": "Modification Station Fragment" }, { "id": 35028, "count": 2, "progression": true, "tech_type": "MoonpoolFragment", "name": "Moonpool Fragment" }, - { "id": 35029, "count": 3, "progression": true, "tech_type": "BaseNuclearReactorFragment", "name": "Nuclear Reactor Fragment" }, - { "id": 35030, "count": 2, "progression": true, "tech_type": "PowerCellChargerFragment", "name": "Power Cell Charger Fragment" }, - { "id": 35031, "count": 1, "progression": true, "tech_type": "PowerTransmitterFragment", "name": "Power Transmitter Fragment" }, + { "id": 35029, "count": 3, "progression": false, "tech_type": "BaseNuclearReactorFragment", "name": "Nuclear Reactor Fragment" }, + { "id": 35030, "count": 2, "progression": false, "tech_type": "PowerCellChargerFragment", "name": "Power Cell Charger Fragment" }, + { "id": 35031, "count": 1, "progression": false, "tech_type": "PowerTransmitterFragment", "name": "Power Transmitter Fragment" }, { "id": 35032, "count": 4, "progression": true, "tech_type": "ExosuitFragment", "name": "Prawn Suit Fragment" }, - { "id": 35033, "count": 2, "progression": true, "tech_type": "ExosuitDrillArmFragment", "name": "Prawn Suit Drill Arm Fragment" }, - { "id": 35034, "count": 2, "progression": true, "tech_type": "ExosuitGrapplingArmFragment", "name": "Prawn Suit Grappling Arm Fragment" }, - { "id": 35035, "count": 2, "progression": true, "tech_type": "ExosuitPropulsionArmFragment", "name": "Prawn Suit Propulsion Cannon Fragment" }, - { "id": 35036, "count": 2, "progression": true, "tech_type": "ExosuitTorpedoArmFragment", "name": "Prawn Suit Torpedo Arm Fragment" }, - { "id": 35037, "count": 3, "progression": true, "tech_type": "BaseMapRoomFragment", "name": "Scanner Room Fragment" }, + { "id": 35033, "count": 2, "progression": false, "tech_type": "ExosuitDrillArmFragment", "name": "Prawn Suit Drill Arm Fragment" }, + { "id": 35034, "count": 2, "progression": false, "tech_type": "ExosuitGrapplingArmFragment", "name": "Prawn Suit Grappling Arm Fragment" }, + { "id": 35035, "count": 2, "progression": false, "tech_type": "ExosuitPropulsionArmFragment", "name": "Prawn Suit Propulsion Cannon Fragment" }, + { "id": 35036, "count": 2, "progression": false, "tech_type": "ExosuitTorpedoArmFragment", "name": "Prawn Suit Torpedo Arm Fragment" }, + { "id": 35037, "count": 3, "progression": false, "tech_type": "BaseMapRoomFragment", "name": "Scanner Room Fragment" }, { "id": 35038, "count": 5, "progression": true, "tech_type": "SeamothFragment", "name": "Seamoth Fragment" }, - { "id": 35039, "count": 2, "progression": true, "tech_type": "StasisRifleFragment", "name": "Stasis Rifle Fragment" }, - { "id": 35040, "count": 2, "progression": true, "tech_type": "ThermalPlantFragment", "name": "Thermal Plant Fragment" }, + { "id": 35039, "count": 2, "progression": false, "tech_type": "StasisRifleFragment", "name": "Stasis Rifle Fragment" }, + { "id": 35040, "count": 2, "progression": false, "tech_type": "ThermalPlantFragment", "name": "Thermal Plant Fragment" }, { "id": 35041, "count": 4, "progression": true, "tech_type": "SeaglideFragment", "name": "Seaglide Fragment" }, { "id": 35042, "count": 1, "progression": true, "tech_type": "RadiationSuit", "name": "Radiation Suit" }, { "id": 35043, "count": 2, "progression": true, "tech_type": "PropulsionCannonFragment", "name": "Propulsion Cannon Fragment" }, { "id": 35044, "count": 1, "progression": true, "tech_type": "RocketBase", "name": "Neptune Launch Platform" }, { "id": 35045, "count": 1, "progression": true, "tech_type": "PrecursorIonPowerCell", "name": "Ion Power Cell" }, - { "id": 35046, "count": 2, "progression": true, "tech_type": "FarmingTrayFragment", "name": "Exterior Growbed Fragment" }, + { "id": 35046, "count": 2, "progression": false, "tech_type": "FarmingTrayFragment", "name": "Exterior Growbed Fragment" }, { "id": 35047, "count": 1, "progression": false, "tech_type": "PictureFrameFragment", "name": "Picture Frame" }, { "id": 35048, "count": 2, "progression": false, "tech_type": "BenchFragment", "name": "Bench Fragment" }, - { "id": 35049, "count": 1, "progression": true, "tech_type": "PlanterPotFragment", "name": "Basic Plant Pot" }, - { "id": 35050, "count": 1, "progression": true, "tech_type": "PlanterBoxFragment", "name": "Interior Growbed" }, - { "id": 35051, "count": 1, "progression": true, "tech_type": "PlanterShelfFragment", "name": "Plant Shelf" }, + { "id": 35049, "count": 1, "progression": false, "tech_type": "PlanterPotFragment", "name": "Basic Plant Pot" }, + { "id": 35050, "count": 1, "progression": false, "tech_type": "PlanterBoxFragment", "name": "Interior Growbed" }, + { "id": 35051, "count": 1, "progression": false, "tech_type": "PlanterShelfFragment", "name": "Plant Shelf" }, { "id": 35052, "count": 2, "progression": false, "tech_type": "BaseObservatoryFragment", "name": "Observatory Fragment" }, - { "id": 35053, "count": 2, "progression": true, "tech_type": "BaseRoomFragment", "name": "Multipurpose Room Fragment" }, + { "id": 35053, "count": 2, "progression": false, "tech_type": "BaseRoomFragment", "name": "Multipurpose Room Fragment" }, { "id": 35054, "count": 2, "progression": false, "tech_type": "BaseBulkheadFragment", "name": "Bulkhead Fragment" }, - { "id": 35055, "count": 1, "progression": true, "tech_type": "Spotlight", "name": "Spotlight" }, + { "id": 35055, "count": 1, "progression": false, "tech_type": "Spotlight", "name": "Spotlight" }, { "id": 35056, "count": 2, "progression": false, "tech_type": "StarshipDesk", "name": "Desk" }, { "id": 35057, "count": 1, "progression": false, "tech_type": "StarshipChair", "name": "Swivel Chair" }, { "id": 35058, "count": 1, "progression": false, "tech_type": "StarshipChair2", "name": "Office Chair" }, @@ -70,8 +70,8 @@ { "id": 35068, "count": 1, "progression": false, "tech_type": "VendingMachine", "name": "Vending Machine" }, { "id": 35069, "count": 1, "progression": false, "tech_type": "SingleWallShelf", "name": "Single Wall Shelf" }, { "id": 35070, "count": 1, "progression": false, "tech_type": "WallShelves", "name": "Wall Shelves" }, - { "id": 35071, "count": 1, "progression": true, "tech_type": "PlanterPot2", "name": "Round Plant Pot" }, - { "id": 35072, "count": 1, "progression": true, "tech_type": "PlanterPot3", "name": "Chic Plant Pot" }, + { "id": 35071, "count": 1, "progression": false, "tech_type": "PlanterPot2", "name": "Round Plant Pot" }, + { "id": 35072, "count": 1, "progression": false, "tech_type": "PlanterPot3", "name": "Chic Plant Pot" }, { "id": 35073, "count": 1, "progression": false, "tech_type": "LabTrashcan", "name": "Nuclear Waste Disposal" }, { "id": 35074, "count": 1, "progression": false, "tech_type": "BasePlanter", "name": "Wall Planter" }, { "id": 35075, "count": 1, "progression": true, "tech_type": "PrecursorIonBattery", "name": "Ion Battery" }, @@ -79,5 +79,5 @@ { "id": 35077, "count": 1, "progression": true, "tech_type": "RocketStage1", "name": "Neptune Boosters" }, { "id": 35078, "count": 1, "progression": true, "tech_type": "RocketStage2", "name": "Neptune Fuel Reserve" }, { "id": 35079, "count": 1, "progression": true, "tech_type": "RocketStage3", "name": "Neptune Cockpit" }, - { "id": 35080, "count": 1, "progression": true, "tech_type": "BaseFiltrationMachine", "name": "Water Filtration Machine" } + { "id": 35080, "count": 1, "progression": false, "tech_type": "BaseFiltrationMachine", "name": "Water Filtration Machine" } ] diff --git a/worlds/subnautica/locations.json b/worlds/subnautica/locations.json index 81df2153..806fc45e 100644 --- a/worlds/subnautica/locations.json +++ b/worlds/subnautica/locations.json @@ -41,7 +41,7 @@ { "id": 33010, "position": { "x": -1396.3, "y": -330.8, "z": 730.0}, "need_laser_cutter": false, "can_slip_through": false, - "name": "Dunes Wreck - PDA" }, + "name": "Dunes North Wreck - PDA" }, { "id": 33011, "position": { "x": -1409.8, "y": -332.4, "z": 706.9}, "need_laser_cutter": true, "can_slip_through": false, @@ -380,7 +380,7 @@ "name": "Aurora Drive Room - Upgrade Console" }, { "id": 33095, "position": { "x": 991.6, "y": 3.2, "z": -31.0}, - "need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true, + "need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true, "name": "Aurora Prawn Suit Bay - Upgrade Console" }, { "id": 33096, "position": { "x": 952.1, "y": 41.2, "z": 113.9}, @@ -497,7 +497,7 @@ { "id": 33124, "position": { "x": -30.4, "y": -1220.3, "z": 111.8}, "need_laser_cutter": false, "can_slip_through": false, - "name": "Alien Thermal Plant - Yelow Alien Data Terminal" }, + "name": "Alien Thermal Plant - Yellow Alien Data Terminal" }, { "id": 33125, "position": { "x": 245.8, "y": -1430.6, "z": -311.5}, "need_laser_cutter": false, "can_slip_through": false, From 0fed7f129573afda9c494ce9dbb620fdd80e97bf Mon Sep 17 00:00:00 2001 From: espeon65536 Date: Tue, 5 Oct 2021 17:52:03 -0500 Subject: [PATCH 16/27] Core: do not error on location exclusion if the location has an ID value --- worlds/generic/Rules.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/worlds/generic/Rules.py b/worlds/generic/Rules.py index ed9b5542..e442a66e 100644 --- a/worlds/generic/Rules.py +++ b/worlds/generic/Rules.py @@ -23,10 +23,13 @@ def locality_rules(world, player: int): def exclusion_rules(world, player: int, exclude_locations: typing.Set[str]): for loc_name in exclude_locations: - location = world.get_location(loc_name, player) - add_item_rule(location, lambda i: not (i.advancement or i.never_exclude)) - location.excluded = True - + try: + location = world.get_location(loc_name, player) + add_item_rule(location, lambda i: not (i.advancement or i.never_exclude)) + location.excluded = True + except KeyError as e: # failed to find the given location. Check if it's a legitimate location + if loc_name not in world.worlds[player].location_name_to_id: + raise Exception(f"Could not find location {loc_name} in player {player}'s world.") from e def set_rule(spot, rule: CollectionRule): spot.access_rule = rule From 53e6ca6e34d42223e5ea578d32a875a1ad081c95 Mon Sep 17 00:00:00 2001 From: espeon65536 Date: Tue, 5 Oct 2021 17:55:15 -0500 Subject: [PATCH 17/27] Core: better error message for exclusion failure --- worlds/generic/Rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/generic/Rules.py b/worlds/generic/Rules.py index e442a66e..9e7892c0 100644 --- a/worlds/generic/Rules.py +++ b/worlds/generic/Rules.py @@ -29,7 +29,7 @@ def exclusion_rules(world, player: int, exclude_locations: typing.Set[str]): location.excluded = True except KeyError as e: # failed to find the given location. Check if it's a legitimate location if loc_name not in world.worlds[player].location_name_to_id: - raise Exception(f"Could not find location {loc_name} in player {player}'s world.") from e + raise Exception(f"Unable to exclude location {loc_name} in player {player}'s world.") from e def set_rule(spot, rule: CollectionRule): spot.access_rule = rule From 3348dce1223dc9b387ed96e2611d614879dec64d Mon Sep 17 00:00:00 2001 From: espeon65536 Date: Tue, 5 Oct 2021 18:39:23 -0500 Subject: [PATCH 18/27] Core: try-except-else style --- worlds/generic/Rules.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/worlds/generic/Rules.py b/worlds/generic/Rules.py index 9e7892c0..dadabd89 100644 --- a/worlds/generic/Rules.py +++ b/worlds/generic/Rules.py @@ -25,11 +25,12 @@ def exclusion_rules(world, player: int, exclude_locations: typing.Set[str]): for loc_name in exclude_locations: try: location = world.get_location(loc_name, player) - add_item_rule(location, lambda i: not (i.advancement or i.never_exclude)) - location.excluded = True except KeyError as e: # failed to find the given location. Check if it's a legitimate location if loc_name not in world.worlds[player].location_name_to_id: raise Exception(f"Unable to exclude location {loc_name} in player {player}'s world.") from e + else: + add_item_rule(location, lambda i: not (i.advancement or i.never_exclude)) + location.excluded = True def set_rule(spot, rule: CollectionRule): spot.access_rule = rule From 916ba2ea4159474bc9869e1be12250573d72ca20 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 6 Oct 2021 02:12:05 +0200 Subject: [PATCH 19/27] Test: test against item/location ID overlap --- test/TestUniqueness.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/TestUniqueness.py diff --git a/test/TestUniqueness.py b/test/TestUniqueness.py new file mode 100644 index 00000000..baf3792c --- /dev/null +++ b/test/TestUniqueness.py @@ -0,0 +1,23 @@ +import unittest +from BaseClasses import MultiWorld +from worlds.AutoWorld import AutoWorldRegister + + +class TestBase(unittest.TestCase): + world: MultiWorld + _state_cache = {} + + def testUniqueItems(self): + known_item_ids = set() + for gamename, world_type in AutoWorldRegister.world_types.items(): + current = len(known_item_ids) + known_item_ids |= set(world_type.item_id_to_name) + self.assertEqual(len(known_item_ids) - len(world_type.item_id_to_name), current) + + def testUniqueLocations(self): + known_location_ids = set() + for gamename, world_type in AutoWorldRegister.world_types.items(): + current = len(known_location_ids) + known_location_ids |= set(world_type.location_id_to_name) + self.assertEqual(len(known_location_ids) - len(world_type.location_id_to_name), current) + From c5193ffdd92da26264d62893d29135c7931fb015 Mon Sep 17 00:00:00 2001 From: CaitSith2 Date: Tue, 5 Oct 2021 21:12:26 -0700 Subject: [PATCH 20/27] GT flashing now disabled by reduce flashing. --- worlds/alttp/Rom.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index efedecb0..c3367267 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -1801,12 +1801,16 @@ def apply_rom_settings(rom, beep, color, quickswap, menuspeed, music: bool, spri rom.write_bytes(0x123FE, [0x72]) # set lightning flash in misery mire (and standard) to brightness 0x72 rom.write_bytes(0x3FA7B, [0x80, 0xac - 0x7b]) # branch from palette writing lightning on death mountain rom.write_byte(0x10817F, 0x01) # internal rom option + rom.write_byte(0x3FAB6, 0x80) # GT flashing + rom.write_byte(0x3FAC2, 0x80) # GT flashing else: rom.write_bytes(0x17E07, [0x00]) rom.write_bytes(0x17EAB, [0x85, 0x00, 0x29, 0x1F, 0x00, 0x18]) rom.write_bytes(0x123FE, [0x32]) # original weather flash value rom.write_bytes(0x3FA7B, [0xc2, 0x20]) # rep #$20 rom.write_byte(0x10817F, 0x00) # internal rom option + rom.write_byte(0x3FAB6, 0xF0) # GT flashing + rom.write_byte(0x3FAC2, 0xD0) # GT flashing rom.write_byte(0x18004B, 0x01 if quickswap else 0x00) From f7ecf02bebd948b5816aefbd32f1db7fb7de6715 Mon Sep 17 00:00:00 2001 From: Jarno Westhof Date: Sun, 3 Oct 2021 22:02:41 +0200 Subject: [PATCH 21/27] Added timespinner to graphml --- docs/network.graphml | 3195 ++++++++++++++++++++++++++++++------------ 1 file changed, 2303 insertions(+), 892 deletions(-) diff --git a/docs/network.graphml b/docs/network.graphml index 3e11c69a..ce19b883 100644 --- a/docs/network.graphml +++ b/docs/network.graphml @@ -1,892 +1,2303 @@ - - - - - - - - - - - - - - - - - - - - - - - Archipelago Server - - - - - - - - - - - - - - Factorio - - - - - - - - - - Folder 1 - - - - - - - - - - - - - - - - FactorioClient - - - - - - - - - - - Factorio Server - - - - - - - - - - - Factorio Games - - - - - - - - - - - Generated AP Factorio Mod - - - - - - - - - - - - - - - - WebHost (archipelago.gg) - - - - - - - - - - - - Folder 3 - - - - - - - - - - - - - - - - WebHost - - - - - - - - - - - Flask WebContent - - - - - - - - - - - AutoHoster - - - - - - - - - - - PonyORM DB - - - - - - - - - - - - - - - - - Unity/.Net - - - - - - - - - - Folder 5 - - - - - - - - - - - - - - - - Mod with Archipelago.MultiClient.Net - - - - - - - - - - - Subnautica - - - - - - - - - - - Risk of Rain 2 - - - - - - - - - - - - - - - - - Java - - - - - - - - - - Folder 6 - - - - - - - - - - - - - - - - - - - Minecraft - - - - - - - - - - Folder 4 - - - - - - - - - - - - - - - - Minecraft Forge Server - - - - - - - - - - - Any Java Minecraft Clients - - - - - - - - - - - - - Mod with Archipelago.MultiClient.Java - - - - - - - - - - - Slay the Spire - - - - - - - - - - - - - CommonClient.py - - - - - - - - - - - - - - A Link to the Past - - - - - - - - - - Folder 2 - - - - - - - - - - - - - - - - Z3Client - - - - - - - - - - - SNI - - - - - - - - - - - SNES - - - - - - - - - - - LttPClient - - - - - - - - - - - - - - - - - Ocarina of Time - - - - - - - - - - 1 - - - - - - - - - - - - - - - - Z5Client - - - - - - - - - - - Lua Connector - - - - - - - - - - - BizHawk with Ocarina of Time loaded - - - - - - - - - - - - - - - - - - - - - - - - - WebSocket - - - - - - - - - - - - - - - - - - - - - gRPC - - - - - - - - - - - - - - - - - - - - - Various, depends on SNES device type - - - - - - - - - - - - - RCON - - - - - - - - - - - - - - - - - - - - - UDP - - - - - - - - - - - Configurable (waitress, gunicorn, flask) - - - - - - - - - - - Subprocess - - - - - - - - - - - Subprocesses - - - - - - - - - - - SQL - - - - - - - - - - - - - - - - - - - - - SQL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TCP - - - - - - - - - - - - WebSocket - - - - - - - - - - - - QModLoader - - - - - - - - - - - - BepInEx - - - - - - - - - - - - Mod the Spire - - - - - - - - - - - - Forge Mod Loader - - - - - - - - - - - - WebSocket - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WebSocket - - - - - - - - - - - - WebSocket - - - - - - - - - - - - Integrated - - - - - - - - - - - - Integrated - - - - - - - - - - - - WebSocket - - - - - - - - - - - - LuaSockets - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {"version":"2.0.0","theme":{"name":"light","version":"1.0.0"}} + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + Factorio + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + FactorioClient + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RCON + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UDP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + WebHost + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + AutoHoster + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Subprocess + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SQL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SQL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + .Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + Unity + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + Subnautica + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + FNA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + Timespinner + + + + + + + + + + + + + + + + + + + + + + + + + + QModLoader + + + + + + + + + BepInEx + + + + + + + + + TsRandomizer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + + Java + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + Minecraft + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TCP + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + CommonClient.py + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + Z3Client + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + SNI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + SNES + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + LttPClient + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gRPC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WebSocket + + + + + + + + + + + + + + + + + + + + + + + + + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + Z5Client + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LuaSockets + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WebSocket + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Subprocesses + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WebSocket + + + + + + + + + + + + + + + + + + + + + + + + + + + WebSocket + + + + + + + + + + + + + + + + + + + + + + + + + + + WebSocket + + + + + + + + + + + + + + + + + + + + + + + + + + + Integrated + + + + + + + + + + + + + + + + + + + + + + + + + + + Integrated + + + + + + + + + + + + + + + + + + + + + + + + + + + WebSocket + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 29a207b73ec78ad56cc0562be23134b8ed83239d Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 6 Oct 2021 10:46:42 +0200 Subject: [PATCH 22/27] Docs: update networkgraph --- docs/network.graphml | 3305 +++++++++++++----------------------------- docs/network.png | Bin 111595 -> 112989 bytes 2 files changed, 1003 insertions(+), 2302 deletions(-) diff --git a/docs/network.graphml b/docs/network.graphml index ce19b883..12624842 100644 --- a/docs/network.graphml +++ b/docs/network.graphml @@ -1,2303 +1,1004 @@ - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {"version":"2.0.0","theme":{"name":"light","version":"1.0.0"}} - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - Factorio - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - FactorioClient - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RCON - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UDP - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - WebHost - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - - - - AutoHoster - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Subprocess - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SQL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SQL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3 - - - - - - .Net - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3 - - - - - Unity - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - Subnautica - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 4 - - - - - FNA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - Timespinner - - - - - - - - - - - - - - - - - - - - - - - - - - QModLoader - - - - - - - - - BepInEx - - - - - - - - - TsRandomizer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 4 - - - - - - Java - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - - Minecraft - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TCP - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - - - - CommonClient.py - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - Z3Client - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - SNI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - - - - SNES - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3 - - - - LttPClient - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - gRPC - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WebSocket - - - - - - - - - - - - - - - - - - - - - - - - - 7 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - Z5Client - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LuaSockets - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WebSocket - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Subprocesses - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WebSocket - - - - - - - - - - - - - - - - - - - - - - - - - - - WebSocket - - - - - - - - - - - - - - - - - - - - - - - - - - - WebSocket - - - - - - - - - - - - - - - - - - - - - - - - - - - Integrated - - - - - - - - - - - - - - - - - - - - - - - - - - - Integrated - - - - - - - - - - - - - - - - - - - - - - - - - - - WebSocket - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + Archipelago Server + + + + + + + + + + + + + + + Factorio + + + + + + + + + + Folder 1 + + + + + + + + + + + + + + + + + FactorioClient + + + + + + + + + + + + Factorio Server + + + + + + + + + + + + Factorio Games + + + + + + + + + + + + Generated AP Factorio Mod + + + + + + + + + + + + + + + + + WebHost (archipelago.gg) + + + + + + + + + Folder 3 + + + + + + + + + + + + + + + + + WebHost + + + + + + + + + + + + Flask WebContent + + + + + + + + + + + + AutoHoster + + + + + + + + + + + + PonyORM DB + + + + + + + + + + + + + + + + .Net + + + + + + + + + + Folder 5 + + + + + + + + + + + + + + + + + Mod with Archipelago.MultiClient.Net + + + + + + + + + + + + + + + Unity + + + + + + + + + + Folder 4 + + + + + + + + + + + + + + + + + Risk of Rain 2 + + + + + + + + + + + + Subnautica + + + + + + + + + + + + + + + + + FNA + + + + + + + + + + Folder 4 + + + + + + + + + + + + + + + + + Timespinner + + + + + + + + + + + + + + + + + + Java + + + + + + + + + + Folder 6 + + + + + + + + + + + + + + + + + + + + Minecraft + + + + + + + + + + Folder 4 + + + + + + + + + + + + + + + + + Minecraft Forge Server + + + + + + + + + + + + Any Java Minecraft Clients + + + + + + + + + + + + + + Mod with Archipelago.MultiClient.Java + + + + + + + + + + + + Slay the Spire + + + + + + + + + + + + + + CommonClient.py + + + + + + + + + + + + + + + A Link to the Past + + + + + + + + + + Folder 2 + + + + + + + + + + + + + + + + + Z3Client + + + + + + + + + + + + SNI + + + + + + + + + + + + SNES + + + + + + + + + + + + LttPClient + + + + + + + + + + + + + + + + Ocarina of Time + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + Z5Client + + + + + + + + + + + + Lua Connector + + + + + + + + + + + + BizHawk with Ocarina of Time loaded + + + + + + + + + + + + + + + + RCON + + + + + + + + + + + + + + + + + + + + + + + UDP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configurable (waitress, gunicorn, flask) + + + + + + + + + + + + Subprocess + + + + + + + + + + + + SQL + + + + + + + + + + + + + + + + + + + + + + + SQL + + + + + + + + + + + + + + + + + + + + + + QModLoader (BepInEx) + BepInEx + TsRandomizer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TCP + + + + + + + + + + + Mod the Spire + + + + + + + + + + + Forge Mod Loader + + + + + + + + + + + + + + + + + + + + + + + gRPC + + + + + + + + + + + + + + + + + + + + + + + Various, depends on SNES device type + + + + + + + + + + + WebSocket + + + + + + + + + + + LuaSockets + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WebSocket + + + + + + + + + + + + Subprocesses + + + + + + + + + + + WebSocket + + + + + + + + + + + WebSocket + + + + + + + + + + + WebSocket + + + + + + + + + + + Integrated + + + + + + + + + + + Integrated + + + + + + + + + + + WebSocket + + + + + + + + + diff --git a/docs/network.png b/docs/network.png index 7eb996e217443afb6d21db0333756ecf275254c4..86691d2fd2fed5e695cad658ed856c1d3e97644c 100644 GIT binary patch literal 112989 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%0DA}Hpou05gqiVHY^F^p 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 literal 111595 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 }yGFx8!&osHG?q^%BBm8Zz*RGng z0$G8AhKwyPxo07{7_Zk>u;3q$G9f4fAaS=HOq1t> zmm7E}AsXbhm5A{z8q5;I7%yakpAv=ioJP6rqM7pM6*+&c0jci8iZ~-Tzw9ikm)p7z`WS-tdwvpJGIm{cD5esKChB@AMhsnI%gygjh%_Kf%2APXk#`5 zCHrY#sQ~Y0#AkjMTg)oa%|yBk*4GjVl@Gvx#l1OiYV>KluST$%ZXHOskH(G*3%f&<=%?$%eFG&nf}o==93 z`p&gh5S<&h{T0@l?0f>cbA9lga!yO{hBKH%W0c-8sRGuFGFFrET`0ESQAl|(LuQkg zHDPM?Y&eBkL?Jf_l=1t{FJM#o(8xRMvf8v`8bOKcWEI5p}Qt17z=V%>xE7Q~oW zyB5FX23@NLZEc6;R+Ck)k!h03F?~ycz817K&+iw*=c2%H$>|vCX#gOFiEifd6SyyQlXBCK9_r|)F;EFzE zp%+RT7-VZ6n>U+Uofb$-zjt?mjo?c2@!>Ob!>tUG%3U(=D-7wF!QrP2CeZF zpzWr$ZWwQ9-P+d>s?-zkJ060x4 z522&o8^%Rt~W2`EIFILb>}|D+;>>e`b8)wez3;FNHVps&6rkTC+uWAf>^WXU`s#p84p93EEusnUP8GG{DKtR%m#SP4R%kyU?@qd~Pcm zFIWs5EMPT(Qx(5xiDj-QodKAVOQQ)_2IxOnehm3T{kiS3hKxQvrT);(HAY<-E11X{ zGnni)!234dyUFywwr$=+$;nQ-`vm({k=GGNo0fe`)Y)Dow_!1SUN z0xM1usXc$Bb!8>owTmZVYX}*)gk>;Y&h`BIsaYE7D zaCIxw=i9|GgkIX>gTnj#10|>5j1nG~mic@g*Kq0X%BnV*fiMi3ZDSS3p9Ir8(-fG? zFTML!=v%qXj`v}3fIz#2$NS9|S)14tsM5w%_b$~LadU6OhyoQlxH0dx6x{54H}w41 zy|f;Co_AAmH{o+|p&YZdGwq{~4?{7_zoQ$Vo}#6ACD{kH+plVM`3NPH%OSybIERHV zwyDwtf6_e$rIif#!Q{Zn$x_{eO~eoiG5jTs&}q|32fSNPWMTI45w}>9$NP};YZ#l@ zhXQ0(1K*L_=q~hzr;neqWO>6zJ$5i4L0Mx!hw5eA?{!t%fZUeQO1ZY`6a6WD&jMpM zu#XZlrar;~qLTTLzf?j18WhK!fs|>+o^D3~QoPgtsrX@TA?Mx4T6%gW*_m6XBijgH z)R>~0-MO7^w*+4$Yog10;1}TFeBEGcY{*_*<%gUuJ5mb1pBQEX`$QELXt3cF^nIn^T9FSv zn2e+ApQrm*AO zb+0Zzi@mZ_8!d^cz5?jfoD)3-HNv%#Q|Alcc_3RtXfbE5zXi%N*HhO>{gfS& zVcseFOL3vZlRQH0CvAY_wIlgXsjF7C=Q5t`TN#{aeIUt@JibzFLw}=#8ZD~*rGrT7g-Jv z)-!JVSC)zh?Bs2`JovUZ#W)~Q{slH`TT->`c5?IxiU^ z2@M^JSmo?i{%ZhuEzyFiVYJ)Z88%4qk8788t0`t?W(E*R^G|~K#deW_o9uHV|AaC) z>=UQ&4%sC9o#ik12?G5J?^2DE7ZzMi_UNBun{+XcFa}pT8$S5`(m4PExRAcfR00lY z>DRIe?Cb`||IY>-`nK#Eg4l~N#_4~38oBd2@N_qg|BoO4dp3E=)d&F-zz1mt0Mt=7 z+9o5M0q|)F*nN&<+e_@aH$!li;6?S@ff=Y!p+Xn^?xVXEzsg%EAL31Mvx%G)osqC5*|$g$VE0~T&S$rriWly)R?m8Dqa z9l0uD(ciPf(X|9Py3BXFIk(Ne>+M-FNNrdpbnhTNlg<4k_N?{yq)tofazw;^qQ_`{ z<2a^lOS8NNXj1&QUw}|b%G56cFHk=I#X$!&xV^m~_J4iv->RAHo;Xs%{~qm&UD-v7 zS2{Rq?Y$H9YRp~j@qyT;W zwzoZ+@ipZ#N0Y`7LtWT`BLem*@OmoH{%;`TqCvJP978qN&5&*zkd+QtcLL6A1j7#) zzpDQ3tYvqQW97In_ITtuj-R3n+0j55@*l}~WmT2c!3S0V-VE%dY7!hhPsO|Adh>P0 z&Nu@HloV#(d3n!%2rscfxxr6IUJw;+O*vsU1WWjj-{kp+*-4e^zHP)#;z6|0Tr1z< zX7@ngn9xA2mm_AiU3|ngoWHtNAaG+*^9Xf3T#ZLo!ui^77nD9P$z8g!_s;gKF|Ue$ z!idkWmU>LI%nw%;+OR`q23d|6R0YH{3uyrM^e0R4gocAd0Z_Kyxpo(tqog_~aXf}s zhJ9{q)$Q(aDdd>j*+;cyE_J)JY?VNSH40{&_F^@|f(` z2ZzkE1mAfXWP_io$0P_q2OenKw%-$j#+1IdWbc!K2!OsaJ71;OzjqkrG_PFyfv%=; z)og;Ycd+%;Q4*1veRXUl8DH^=nRU?~GG+D%M!zESCl?e zk4>-^eDKE$kZ#Nq&i$h?#loVi}>2PZ?h5{(z}`|zpd$@5EMx-5N{v1?9J+((m?Hmw85jqjOR zexu*~_jiM*uf;bo&0H*P=11BTO%^Y-HB5*RCb$x*Ll$BO&;IMijZvO%tb?kMT+nZ z%J+__N4qyfR+r)m-+l^dNyLj1FX;w|54Ea$lga;?OIZq7q9 z%VUmoDLNE^mtRqG{X0Tuz*^LviM)H{5#N!@*^ugG#A%;;t>%WBYr#`VHr?OfXQ%J_ z+g-0=Xq@wI^0Yp4A+GYn4mGXm#FSi?ah;lfn(iF9Jz6)MFn__BDr(3GFq}3}Nt|xV z%wwS~=NqEEHy-q+hwF&)U&|Vhdn-`WA=``2%@2ep$Bs#AE}x%HL5;(|PhNaDEeU%@Jl?FGg zBTy_gat-HeEji_@0KpL8N*7;*^<9-BIkwyvF|Zzxcq?bpx>%KaMq=45;tIkA*K<*W zww^SNU#ij3rX*EdZa0A^)@6%9YSXLDz;iKr`F-4nw~9Z7Os8p)PEM&3)3&%1ltL_B zaP3*6k$_;eyyo6m)pcWJ)gi;Gkm`F z%~suc);5-@4W2*bc1l01mwufA1?o=mS0p3U{5MC|EazgQ^L@)+s&%|F$p;9VQ{th* zdTV?0m5IM6N?-&MS}+$LlwM}6#8s2`H)?wDHP>MMV&D0N8cd`<8X;eDo^EYSu1~#E zZqmvmjtlhLEpjfN5sq65?ow=(YV?Ol=kkMR5YA!5vmzKT=%>XwRK5`P=n2`>vldi@ zabc?B#rCGHbHbcD$$A@e;mJD5a?Z1qlLo=xP}Z=Uc1r+aPOfbyh1{vueZ?>ua5LogE&J@r|u^q z)QCfFSW>g8+WEL}dvr!XFg>=>=_?uz98oCawuU7u%-(b!ah;0?y=LcF8!-*A%JLegZwH9QyHkmUsN1Zl=KHY=#q*JR%Sxc6Q48l+Fgv zK-`FC0N-&Y4X=U*l}pvntafzlr}yN*JC*J{&G)kki$jsL2GsnW>Fp{zA~~@Z!p{zy z`OVClw-LuU9^3jed-t^uyg+LcnOB3iv%J49so>r4TJlEu2}B)EG?G^)luCzN3t};s z5S|^EW@b2vF(R(6R%2T}R;o8#b@8W5Et@OmMj&c-I^@xba4o^x*C1KPg&keBZJV^l z17nIjSH>;MUE_t_$BMMvu6=V^1@iZSkc{yA75k=J~jDB(;s#9;0};N zX!3di+Xe42H6fSBNMBs>5$>VKad#sfl}8|jkIo&^$=5Ov21ONZI93Illl^ z9-RX(bN(_Et0%S;a?Jzq!@K3Yoybl9AyB}J713{Sl^BgodT9_!Upi537V6y1pD$`- z1N$NW9{j1GCgyGRlV0GA%f&QK{F|7r>OW*LE2){B2a95ciHhaAfw$ca^r4U^f9Rq? zEey$hLO0N^e8R{DUgoxA@Sbl4GU}TLfgrNvq`yw;><2}+7461vN`csP9ymIjh$Rq*GjUmVJ#P^s_Yw zq?U8xI*wzPJAHNfETH}kejvK{(ZRcta6t*}@epr2+?mS{=s#!amBKsW`DpoTVB*CW z*+)e-+3IWwlnv!;i!vyQ(6xZj+Me0{+@bK7=#i+YK^lvsq=D;tbOiGh^@ zDdJIrZGv4sPzyyE)s$lGzDFk;09Q7a`^iLFxBve;mSWZ9W5Sj9QG) z-+xJYST=Hi{#dn8;A)Hj&&M%L8ZLa;$s^N^(X{sqJ>98wiD&%Bt2u$Ws-ordAM zm|F@Fo%Idf1?hrAibK|x%I3+R8BPYchtH(_tBn_<4-?%hc7RD8yBIc|MH@KKS#--5 z{CDwx;2`&#?_3}ql=`MyW)IG|U|Xj5TdiSfd~r-n%%5-Uh5c=Tqdd7Ha?S$6HaTX2 zi{^%3ym3D&pf4oNF3S|n@akV4><*$yf|E@ibgZU2^>ezD{t}8cT2$b(>3be>)6#=s zVyb*nGJjE{3|0+6G6RHb12~tpNb@g;GY~=x>VLq?0 zRHNJILFxUhqQM;OF?bDA{39$ft(TfRsE34{%NCYvrsUdw-s*|5val^4;?W?2MK*yP zSJUAJa|_56IXLXoGBZiPGPyfbzy1J<$fG_)>VM5?fN*!;f_qE;|CYM^+hNgN=MU8R z@0f+fAfrV7N3!%k%jy5&i0IC^c1RYU_D`PF816aD=XP4>KcuHk?7o15zJH{rrvq8V zXXfkk|Ebwd7RzqNPCnRWbKo-GL12LFxk|ds3XL@WuL%GLhsd$?sOr4`+Q4v^T(SFE z4#U%br(S!nh-ZdX|1X)v&OzS~x4d|?d1z^aA3eA{{H#aNC{>ZFeVc==I;9WM2a+@2yg35Y41Fz<|ND9$t7_KChp{|Q#|=Q!C$DA?Z1(zL zwaY^;1+y~2*Pb+M&(*s+Yo>a4)b^^NwbEc$xE3VFSfTi~3NJH52G&dk@psZkKy%CW5teYsX76;9X z!$y;T-+q#?gPoKvC+AfFsK9?o*B?{+V7W^#vTrjO6Ylw-t_16?E1KGZ9td{W8R4F% zD#Y_TKN5O&GM}K-+iuY0>UqUt zbsyYpg#j-00+W(Lp>&WFTDT9-%Z}B>^dpPELZYY&h(R)+ZC?&8#4=+e1N^&fZq*{H z9|)PavIjYJxGhB~E3pjv;(N%#t4C_+td4fsD3B}uSNJu0bI1WWAzHU(>^ygK?jX6w zNj5B~b1cuEphP_%RhLbNr&eYsdlEciu3RXK{!B*gV~Tz~$Q@Lq6G!M9&~{)Q!U27AvA6Dk2I3j)0&Ds5GSo zrGtRf&>5sjS9&o)!2&A1DP4LGy@V1eilBgm5+oF*hft&>frNy2gUp~ z#>|(m-0$3T_St)%-+E-wo&w$mX%m*WPhOY~<+T}2M zc?=#sU}xso6Z~i4T5H%E&NJIbE<0#EcBIBDoICJN@<}QtF(>f(L3}#oK?!!=aa7K@ zqj4n`y@FtLO*je}3%paLns~$=FQvpmYVexNX{ibIm1l_|>onk|T)S60$Gu(poBzxl zjrn1XvB{dH1kQxnVAimvkgS0 zdX?SO6OYDg^xJD{CN^+o4jasINfIXK&r8aHO6u~NYi_^vU{zFgbg9EZ{dDZeT=ae) z^`&N5*|Oi9evVv|b7l0bB*&v(u52M4B6r7;z?63@jLvWJa{POBS~W>z}(05hwr49^xd%^a8H! zX*D3oWd}Ukn7t}&hJ@F=nSgI=$6lnJLyAV9`x_Dl50+`TYFo*JaYgLb@%HEC_T8r7 zu==+I&d#LH9elB@!>0<)mQQS#xB~vf@KSA^NWuImP_#ow_4NBR%?z9;T2wfl|Q@>T04 z0KQ-1@XXceujPgOyo{Di^(CN4{+lH*|TSNZ+J`6_9H+7)6{`&h8&ZpdFABf)C=pSA_-o^Y8YWUaAF=c zs$R+lu1M`Dy;7q$fPPVWtg}i&rw_9ZX&>Jo{W99938`Jbp^_uz(pcK9w9yXCzgi6-Z~S!&UVF6ZsKBSnM47RGwSKDoKbX&3_yvn8H4)T!a8?BMw==GUq*)U*v3s{m+y7yFrq@+o8Li=?~oNs_8C(z&nXN zlW6rf?p#>)6R=)8+5U>o;4yZxgNyyur22*RzJIdMLY+hWew5H3eYUoIw1HITEe*2h zxI;6rr$S7kz)G3}MC;$pGKF}DtWUrV5DGPeAkT#fh>7*bg9C!kU*A6@+nI)*e7h`w7B;o+AVFPr|jqz)GQxC2%SP|S9iU24E2C}*%7|Z zSGQwi%WduLk$M+|WQSg=HG@#f#`$^eG_EA?;QY9dPTxLEYC)tWNAX~h(bHv4u1ebH zL1&#&He~quLz$02NJtd9hg+dh@lw>4QcglpB5{DV*0L}ib++0KJ9)s9Fu;Ymzm&AS zx8wNC32=eGSz4eoN-sn~XH@5tlE*V9XT*FRWi3`>ih+Q_~8tFrW8m6RNsfRQ>IkV}i)g%kM&$7Gi7xt7~NnUU1XO+OW^f+!U^ znj4+Yy@EkYN#5YccVF*cZCQqP!G{9js+lI@?lrVCq!JN41&w%&?8q;WXvFN`P-E=N(Tb_P~VgGHTY(wII;gnlH`^s zYV3+tQr?aSZJ=sYojjA=TjkTufr6n$A@eVK<-azX^iu<#mP`^cy*3i|1A$49z~|1) z(=^)p!H(hkI?lTI(YB_bavuE$@WfiOO|AK2qU)iI@XM%`LVW_>H_Ll&OBMgh*K#d(+SdZD zzpwP>n2yJUH;#!sJ?OA)0{|3VlKI1m<>p1Drp*U6My2LBuAro}hT2*s=v|#YeW^F ze8QbfSZlm^4+d_)uWaM|FNQutT*P0w0oz%}!9sk(E%zF)F_=j9-60gJaeoZK)IQF*Th zBZTD)kC?;ADFV#?>GC;A4ag(;+v^V9cZYVKHBME=-m?81Qa%GVq! zwmb9dL~N z-8J8}#eJ;QS7;Gv@sQNdv7sE{=C{Zu;e@_jo9dlE%bs*l?n^FLjqcQ}Ftvg|3sc;Q z3H~N#5h#Rea-B5-Cbj*=1uX-M-ICwD#;)yb(<-HxY9i5v2ZAI&4F@m|7F(E!(YCPZ zrm&(^l5uUx`Zy#0lV>S<0`+<@<{8lZ73zCWunFLw?SWO@r$-%bLQBlcX~?FP zgfo#YW|j6Okk&@~C1jUXb)f>KYvyw!QJQwG8b4rBTVhH`8ovoGEix-MEx+yPIB3w| zhBQK$qFhZZ(`Z!BVBb5;-otL}sUAyQ_{n7qYL#`3YDvB=B~N@Q**Sb$XQO#I2+o{T zb;vamekb^Rq5YdOBDx(cTvs1lZb9rtr{&jw!7M1XfDG)G^aH_cZk%U98hR7G zQYy1UN^i_E^_|<|3j-Z{}Nkwyt8zsLMuDU<& zG6w5h<+!$}E|&_6A92T;beKPA@?C~)N8@;8Nq+Zb9uHKM(@F`mfKu?T17B_?@^$;0 zSmT@07w$LAYSUr)JA2Y#5z>Q@kHww6P&jSD+nPrZY`qLGV`izXpWI)A1jBClRHeVa zf9Z3j*tE1BO5%6vza>^TS6d>z3`nJ=&uzU`=5hnvMrENzvJkkWdGDBKC8WBHzrcB* zcm^@og!v&r#-=ZNmcz+wtPn>x^#v51Y)Q4G-HwHyEow1IEU;|**k#pZO5fHmV?NF&n7XK0U`L)0_BZ{lfTBQF1QOFzPY(<%qbZ2gcW?53xld49Q{9m13 zXkF~6n$d39!j4lW6v^{Bx17+K)xP6~Na8zdcq?qvGZGi_E|MI1EoewQ7516Id-UC_ z<%Vsg665ACLC1*Zzl}f(-My|JGRR|p7mnB=ysmHJn<(qsCzu2io;E)J;YWNN~eYidY zs=}BlpF3VLqvH3`vKywaoPI@-JA?&^Z4;3z>TZ&q^J+14H_Dt}^@89#!27^;2_XiO zB%IAPzX@A58k5EY5!yF?>`(O>apbu1AcMY_)g*k0yQJ?046^G?7jv~!3%9o)K^1jf zWM!jAL3zU}msIVTHzm5nwVR9Z{VJRO6L;f^i?2ZUYV^j8fOOHT{$dyKJ@%sl?^fyc zFJj)nHFW_bf&&NG&A)>m0xqEha7J~eE>~`i14d4XX?0h1hMIMd^2HdTJH~;*sv#=f z1BAy}w`))AzZEC=cUiTId+(N;t5vq0C#hsSqV)7Y5M@aU8VmNPl4~{}=fkDOzYdq% zSU5)w)4<<21Rzg`7moHBy*m>{tYhp6I%ch+{4UHLa|mb}UyK*CTRu(w9w- zkg24Jc#xwxt+B2Fcf^O2O2QV%fuK8@3B9Q@n29;Mu&%=H^Qh%jx>SySx-x)Vc;YFO zvp@{c%lsolCFh5OCz`u zXT%`5Yx9xIAY-pix7E?nA;taxeEv)~B<>=h5@}GDYSS%Y1j8Vu2L3_!`kB)(pdbVu zTTO(mxpd0h>obxrZ?xsNYzOmo+YrFdn$xZBR+ehy5U@&K5E$-$!2_QUs*PR**6BYH zgT%AfZ9|b>xJ;nw-Nb&rOea=>^9P^b#SDEf&A%dtU9#Kd9)caQitT?&?>}<3c0f(7rm~AGJU(0oERf0S50Ys+ar)YQ zK#nq}^MM=S>jl6$+X$?I^zldQTA+BmO<6&qAaY3l(gtAt?KBu{HQ_t@P<60Czk^54 zjTgncBzb#OC5KaHdF`_(Mx9f63K$q>_=JVEB&B6qbIl?* z!D~as^$Tx}7C}XWvVGgZ6Q0uvb8~sQ0Z4TgEV4fzqYzpJmY{&#J9ix@v!H;%d!$Mg z5oU?7l-n`pRCcpo9JOfhA*iOSwyI>XYX_Uf067_IkS;tesTt`?2PS>xvPy_}01VJS z2B&xNDuqkmOeZBT%bo-*zE#zG*nC$Te5mRpP+*S$G9UHCh|E$|EMzIbR%xpS>xS1s zxasF0z`N^SS=}X|lUB^-Gu*;blS=xpr@)CyKj9JXNzGWF%W^!{@t;w;j502*5mibaaoeysEm- zQxT*Ed^a_(jvO-K%LOdoU7hh@^@AU`gT{UWyYM<-Wvx)FJDPAb^7VI-FELA!spN~v zE){M|tA{vU-JD;7vUo(tMb)?=Tr$#|Yc;d9jpq0#!ktPcP?2&*fSM=e$8Bf5OB|kV zXM_y>G3MhV!B+%)hcNm!vwvecRFtOp&$@1UI(oi7&R?m%B>aAsQOyKAFsS{@E79ip z+H|mY(0Eo3Gh)B>5DUx4h6I-e3Sv=`I1n7SiGG=gKV`72o`K3FHnuV`e_nNu{zm_G53Lx1SM#@w zlsuk;=nB}^!JtZ4TH8g}h5AE1%z{?IYrTrO(YTDnR}qHHC_#4_?-IVLRR9IF6No-Z zK)H+3E~M&0xaWl)w;M*ol$8Np<(_8Ti5bBWFm__F85RiDlm*21?@fSXz9=$WU4JmB zS52Kk@G#YO;f&ZXLcf2!qtaH!t&nX<0?XO!N?6xgt}xN_PlgX&Z*X6tRTB(>Q@C|) z&UPP^A*|>E<>kx2a6h`9l)to<7r>fF{uj@)HOf`0*LwE|1a z&*qw2SqO%cR>~V}40?+Hq?YF030o_->2O-_ejC83<|V07W!V%^YD5E9H+_7id9Q-g zCpsCp-R>0>07;F#03H6o2rgt7FBQ_y+y=h&5BV9wdWM)I*~y2``?psj7#=^3$^{(V zu;0k*Uyvw$ZwIG%^YQd*FJ!0gB*Urj=DiGe0Q2_0znOi+s1HDYbW}}mL;_=;MW4W6 zdJEW8qrn`C1*h_xV4jAA{g*SSM*3usH&Qv*K(M zeQZOT-y{eXR4@|(X?lx3%mDlx3-pzi zrDYmO36>Ijh?6z9*fgolo$%=wp*<6Eg<=0}sr!E@gw z{piT(H5hmQN6!gfiAVRLss8p*W-e~U+{Tm-Xs7}HoC}Mhm98Xlgdtz{=FJ0;uW_L+ z57>4yvi|{`yW#{ZTJ@i@+v^1f*#;$r6ut z;8E@cmaH=f%R@$Ht~vCH7hn>}S}j|1%}WKVCx<;ZypfgoyQz)k)|0$1obO|@yuaD0 z7U94CxW+eRqt6X{#{Y>|eNFAAA^GLYzfo_nLQl4gfDE<3&v|INflf@1IzzvvAI~|> z!8Ik^ufWB-E?H?B%Ym#CILpV2Am=mp@`|{o1MN1YGZ$n~j$rHsiFI0Lxh@L=TLszd zXd0S6fdp8lGpS06iZqbda*#po3^87ebI5 zVAKf_BPR05^+ca~-I|Kklb8LL>~aBl$YWd?x5diXuX=3W^_C-_x3lNY&T2R|_;}Js zu zl@l!k3LqD*11I%rpfd;KEy57=@fJJ}k!{Ch=6}54A+kDvEpqW7=5+biY;uDhh+d#8 z-S1GFFVTg-J`netRYopxW*TZjw_!Ln03^44o+A~e|_IE-@thD!VNYBYdWVNI9qswQ5~l@%S_te zT(hYHKR*wM`M^wLzcoxRvmAAnwUgC*K??nuL~vVcD6pVcz0Y1BzLZ< zanh|qo}tkLH8uic-aSCZ`NXWstMh_0p|(3o+9cA#Gv**cS~Ha>eLut|tbG?_0`YJQ z=n1AY6z)|h>Ff5NGz9NLkx#zn%_v=R26JnYm86w~SmRr8eV39UpAF+Q=_I&HvQ( zT;CW@w4r*)itntf#NmV?l&wXoH2t54PNWmJ?Gh$d^Xh!b&C?@1MSKx zbVkP91Kq#w6igJ1iT}XrI-x9}uE-f8oIdU(N)Wugj3+HXs#JYn_ow=NE4Uq4?rs&+ z(?$lFO;;(rG^-$LPCA_2sq@BnX~cVMAS>Yw8RXa16L88FA-rIQIyI1MSQG7)F#R$C zaMwZoO3qTO#kw_kKLpty1%H8kCOwGukpKMIa~XR?Qw!*Uw4;PM|=+ZJ=Vi4~0<*s||}C7DnZxxF^tk;WBp z?pB;cg0M+3OS=DEo$&|AH00Jf7;U8Aw8_Kn35=F3u8TNYXA)`U8I#s9by#bAx!)U` zaOF)N`%1H=^BU&VjpygPWEQfe^b$iNNR;*u>-Llh)$JAdZhw9Swte$m$B8hYP}^+; zgFSD{8P9~UY#OQFZ~x`Zy8`{Z1jp%Y{&$%sna-e+8l)EusvGmQ^zxQIHw%^Uu$Vp% z3B1yF$n_qX-TL>k_x#ruom|3vU)uzC7zjrtGC@C__r;+1j8pr(^T``$r#NJJdGyn- zS$NO+MxVgldgSW>g%mWmh%cwDX}?6AC50zxrDl`JV+)CaRj#0VkscORoh*~o!U;_Z z(i6WZL6_8>`(XAE35D&=55K{9IgL8_MlCnrq$t5hrt$mYsUo9;Vyc6sP^$)RpG@ds zNW%H9lRB0`g}K{XmBbs92HxX4g5hUZUp^my_zk%<1qp<*Sb97~b4v6z3s~k8u}hiO zJH9330bk^0Ym9^vMEaoaaz)k7>liM@gDerQ%k{3YD`yepEobKy``!h?`Y9zlFWEkUC4ust? zSSoT32ta4(YRw-?xGCgvah*|D^I@T~Mw1 zmw;slh4W6lxv{P344@@7oZgxNox+izb7uN-yu6B1<9_rEZ4RQ!>f@?#;l`iuU6@5v zW_)hf+F54*kaT*a5M^EiyD$@c>??yisx`UwB)0F^Sa#UO#!b{-_0^b6M7|$g#Q0Rn znrEbprJU{K{k8VESp5w>_OJ^s#ca`=eO2A|BR(YNAf0)iQ6M2=RWix4%)01=E-bM; z`yiIK1#4WxOc&j%G+LmH7!MYk>996a2CPp0iIroy{J=cxbn^W?Y9yK^y>SMkwc!&S z>fj}_d~OAWH!L!;2;}xOns5HiQP4Ew#P9w5hs)CuW~tHdP73#uZ+hl}nL_gjlXH?z zCE{21*wq@_E)C3l29})lEL_q9JO|jXS-0+Yt)EFK)XjSCe2ItNCk92;K&}=iWQ(Wd zXZ5#r5k=p-SICF?SjjIp32ba1a`82D&)V;G4g%b?&nj_rxEJ3Z#`>8GSJ?i>$aB)) z@dYan*?0`OJnf_=$=bZ7v=0Fp9LxsI!*@bFf!M*vYf^J4^Cqb>)J`R|#1ynCysfwb zmYGNRJe|Wih;_6x>u*K;zq8en0@7u7LOtMQBRNEqW-Vz{ndQ+nt--?e9i?_FT4DS` zp!u9PKF%Gpbl2hm=`QN^w7B)Go}B;U>~BkB@ywKV_L#7ePG_e4HH}AaL5&Nkukr#` zKmakK34YX){H6q6I(nWe?jTG1I#FS#8HAi^4HIRpuQ{YC*?t6eAchI1yiGowaRX3% zq<_BOXQ4$G397{i2nLEiDRfF6BSI@B@v(aXd3c(+MekZB)pmdV_ASH<6AJO}gNYUb z$IyVElWo-xh+c#02t?zv^|7=A!bvjv)eE@|9CsfUVv2L*B4oz~=LP5p%`iO;1&I~l z+C7}@NyQ5^T0UA;WzGXYWj8Mc8Hf=$VsH z+sk?vwr&p=IwEXB9G`JYI_E5ra3_#Fx8hW{Wdok3q1HW6DMn4tuh*;;reVfP?2}z` zQ9)alT)yL)Vi$Kxw<>eDD8j9v5Di7d5WT5)n9;Wx@od@sr%XWZ!cs$u)Md)$(&FLt` zZNf$*m@HNekb~;I@#le}R|(zjCa102J>p%}q3e(zKu7{dR`PEL>cOGSXm@-^dRCvJ$OD^0@$LJhIxRp`X(r=^98{GOdyAB0u!CWWEfU;H$yIUMhQ-2#f7aot269* z_%P^FEW|L3|2-68TA?yN zE5ju3BAoZ67(=_xupGN4ct(7c*ZI5Xv&}RZ?uwHSGZ=z-1R1|L>lZ3f9Etx%vbMC- zh@0^EEL^((d>>sU9N)zQI}jy1`3=gT#{3tL{pr8+*ufjPGJ!$?Z!WLZb7RV2IYdsM zVLF^~9n9YZ+^@sQ3E~M1$9aIbGWyM)^YGT?dgEPcOZ+9>afB5Fx;JWG+GlZIV%?YrxfRZQ~>`x)IVW}SnbKUOm{xq?TKobJ7W?={_SA@ z-`kpxuBwT%0_RGWpAsrZfv339WJK>(?BYBAJ2WbYY?-g-=0)g;5MP_xU50p}f6mRK zpA-sCH3#3qgQ1^7@sPivBPDB_B8`7tAavIPk@CN+5<9c=^1wu_HG_n}ilbw<$^l?i zn0J}T#>QW)vzCrAhVHrRhDN#!Pw)jmJSG*>^VcJ=4W^x=6;{qr?Q2)9 zxY*@O*T+dQozEBr$Bb0+M`r-qbQaKYqISt>Cx!ZVodLow?#^h-@Ve4%mGo~b>mQ?P z{?Z@)3HnzN|F(4Qfk#AI9s^3HjQar6D?Is^8#i6tFZHjgeLC{CC0si?sljk^3;^He z1@y()$(sf{@OU7KE)Zb2TW)m4BC~S}B$l;_m<=u*kss<`BIi!6uOS+t32-Ajkt5gP+$^!Z>$S~;E(F~kvFa$upj%Tq7> z78)fM466|JVT^B$d#jgxTF?75|7BlmYIqPTo|b+-e!2aHd>`l!%sKJLdcVK8Az>FM zXWVt4H`Tw+c{tQ~c?F0rW_&eC=KK5b`Sr8Z8)W?G!g+f2<{_W8}VH z=B9WzS_t8)+JaYBukQ{yYgxJ1&8aEJ5*2~tb}_5DjkH&|D>;rBF0>Nev=FZ74gP@E zid4h;#)-&WyZ_41CT^pzmXp}j*E`r_Qj}Zu!5)np_jDaSe}8uhoAF&RH9@n%g*P=o zkm{;?4=40$ZK5?kV9j_%3p^CH+je9^IT)TukAU8b^VH80+H~OdL~rxn&JLO}GL^*3 z%4PLBw%Mn1Rn;otjJu-4zLcw6a+enP^nv!>n+WzHSx1-ATG2w_fTsrC2^jDj%QtB~16KcYXk;X>!ow zi{kcDH9r6?-`YA9Un@G^ALSg0$(r-VklZ0zB_vs;WLK2gJWXl)-h>!Jzk7tR(ajk` z`1x&Y;|sHZW9$46TA+cS)zixCDuOlrpaqyV^a0<4*b<%^=Zc9wRz zlY~0H$l8|~=GFDCbn-QYSFLJCN+=)uiI4MyL?HZXKqt4u4l zP!d^@jp>*;z{7AGC;V1QGaW*DybQ@HvTUaAouQq&Q*GH`xsU5nGzoIrpl*b)fREB7 zBa`CRr`Q8^v(C1hUt?EzEn|R`uWg`Y3mj8R)n;Ts;aQtt3*j3fF zuAhTCXab9d`zSl#SK({6{kf=}9IrKD^jL2xkE3l?kL$=6UJ}#73F3?4Yl;>h$|2jt z#y&$?2SR-58u!$$;wW1R!c4q5>4f`Plzn1C?S&;>)>IZ`TQ%?5h7qWJd@n~`(({qy z-W-Rl$`{R|sSo}vQ)**H)H8EyE~JcL4P}iWZTN*F6B9)4bFdOG;QP=qp%IwE+ca&T zclFiUQ11il6Jr9Wd>4T(z9EHsLq^i0qMzwjkkRI98(Cl-KXHp^aCa`+)>m!EVaj^1 z=mdUHMr4SZ=hc_*u-rFUKfYs|=>@?DKwFNNBQP3S{;?&utB|2&b=F1 zc4ErmoTb<85&QWwa`MI(ct_M3)e%ZuHe&lzJwl7x=VQ`ZKCN8^QZJrI!b|lb&I67wy`utw6{3>n+Gw_faA03Ky;u(*#RnCJHZpUPXVP=2%%p zf7Cv7aw&E^M&*$(Apq!mf(=ScuS$DP9Le_Oi9^yg>)fwFYw|8EEealRZ8OAeSIJcF z?NraGP_N!4(ZxekN|lax1J;DcY?sE+71@Zcz`mgK^*>o_NsmHT=BM+ncO^@A*`62u9 z54o~I%hU{amq|jZjN7Hbd~QAihcEFpJ%>~>v5dTV0jPcU=YCWN@ws}Zh`T;Dz~Uoi zQs)V;_T?ln9*E=`BPplhw{9aR9e-t@6G!@MA}j+;YkN3f!_4_nqHA`? z;pRnn%m}T_X;wHUiRXOxwi<_=_5!s|{F+ny{i@89Gqo%+X=}|`9v5C0uV{WmX(N;j zWNO_J<$bw6@RKvEY(o=YQf}%mVQYP>+ik+uTs7YcqEeOo3%G)^#O0U~lUqK0_lIqFNE;Yv$r5u*nTyhA({hc`;$qO!s3P$v zIgz`CG*6pZc4(#KjrxYLuzm~OOz|B(7#B(qgF)VwDp%$?F9!BHjWUWp*Pdyb3rk$c zIO6UtVNjKGWNsn4l7wFSaKu70127s#e!QO=1bh8pp`rk}^TH|ZIP8i}a&bhy+a?@!dWfq%GH?*PB0-~~2Z$&p(h}-Wf@YKJ+h!tJ|q=+N{w}UPj$n1B^EQ9@& zkR1Me?#3R88$?EJ&ZSd*bc+uOhkVhr%sex95;f)>$dIAxt#Lb5au%Z`0gs6 z(Wuyitz+m%bzdT<{%E;yvc}Yl1L{1S>W)l;n!`#$g+Wd;T+S}yGF`dWfMmRLQwq0W zZ8KQe8$04c85>P_U+aE!XfY`Bw1dhs@^k_1K+Loj)_x&M(+yKC8i_f98N~~9mOrdH zO>$+|fc3=o$jYk4B!?5+LCEupz@#7J{G;jT6W<=*VEJmSHrjTDRI08&s;w)(t+Fuw z!BAGRvIEQ)gf-!%op?k`qapl{tR<;P*eBdfq=x(w@~p%~zm)ru(qr)6Dol$dOLAwM z{I0UQy%1m>W^VN#;u-jm>aiE=>Fpd1|!e{LOoW!B3=KCHPs{KDF$s-D1lu|mZC z2L-E=g*}Cfrdo2I<;!Y?@Au4Yvo#PvIRjTIPvvBiT z+_KmA*~3(<^gL><=k;-n&i=hd<(6 zIx__Mc85c-p^VaJG(qUzgTfj0? z=sCQIwK84zMJeUkvhx%4CCwfC{#>4_hJnUa@}>Up?t@-_wHa2}QT!Z7Ahnp_ZFN-S z27iD!=MTA`r*YAVIoF=4_+YO|R;uKE`F>66W5RU##Mvd%Cra9pA-P(43DZ=$5LnW( z0D()8nLzyZh!x!ULw|Y2edL%?IC<$avhCLpfz{6A0FC^;QUbfR!ld)nQK6KY~}8YM|3JbfnTD6W2;*9&gRVIF(14oz$V(;^lfY1|K; zs==C^nBJ68uw=I6l2(=M7X+CPmzIs4Yx#5^Mp~h1Oq>qX zFC{z;e;}^Ck(qG^cd2FYxO)-w3N*>r#t4BMJ9jN3{Yo;L=sq{f%?EVQkY^?+2^;OG zd2IxqBl>~H2vjAx+Lp~3*c&{~{s8ITvl(OU#r}Ac-chdf=64O~&7{3?=2gT7U^TBV zpks7gP21C+R&-ockBBLoc5vLgYNwvknsuse*&PoZIkoyDB^;a|MWOd2H!7RTdXLoy z#m1&3wRC($yIr6VQ<&u>;q=Vy$dNcLbxQ4OkVfJJFN_xAg>ES=KaNK%`d*8f4io*` zux>{d2vYwZ-~M=DuvoXOs#`Vk0FNbIkfO)@4+{iNbHl%ZgC{TT)YmK>)VZ+r2l=Z1 z$2sr6@HXghRrbG{^wD3i@uomPjG)tS6b%1KoB%(~V376;aLLh3MCx_sp2{Sm

ztBY>r`PAB*-h2?aDbjNPHvCMB<)$fd)qu_e|9a4is&|Mzpez)V3cArf7&SjH@MKd^ z)9R)>&PmSy==wT%>eB|fr*7|JQZsfRG#tNkqP5M`$9xXQXlQY2u#aAnBfqS&*DBL_ z2*UF7@CWgF(sMqz_ZB%>#D~m1A4?H8%FP3@) z0A`*Cyc0UeWk;v^YA}6~cQXI`N&N#n4BG_{c}zn6aQ=_I0wT}5$*V5FN;l9i^meCQ zBU5EPPphpw`UAFVb2V7(%hPj?9w&G>sLPn|n>+UP2Yc%v!RtQ522NvNBu?uM5Z(@M zwfI~89)qo96*vx5IJS<&N4RiZ^d=;P*h=?T7}r1&9^pcpa{hpY>_6ko7mteIl0nk9 zv``-MO9s#m40EvB!w`0X?B2ouug)Z~=!*=R7sI(l?W&kgs>rz?9oZp6M`pZ$oddnV z))sKNaoF=ev!pv>R8_5nECNv*tF>ru04TstxdhJGI1Vm+Z_s+uc&!gp>tXmnizFui zqrCD$ccV*m_EVIt8sa1COr^IkJGM)q-z743oU&&^)HXT4-du8bjGdKqEp-Mt|I0p$ zOA*bjhO!%MtBT;PiKuC6%Fq+;Cci30lcjScLriu+x!|Ku^7 zAeA~~M{;8yRORv4EW@%SOaaC>ixRr~jB|xM0Q= z{4om27S|ARuMZm6-Dq>B#f(iH<{Tr$-&{BXHHd45Q2;aAvh;KYV$URRF-m;{-aaG< zxVJT>M%R6LMiQD23OWq+Zg8xo7yZ%K_sf^mqov}}5PcGk`l}N&h65oO^^gEYJWcXW z;z3fhq$^HRTGi`FOh?JF1Z|YW@OYtPS$D2#b6NU;H}>bHXyI#c1FVI< zymG+>@)c{h&H&8_?EHYxae-PAjxzE;>a zeq=myI%?PL^saQm-2cnl6sn8$jsos-3xU>AujLn#{wx{4FPwakw;JMiL+x&QG=CG- zzf8Ev4V>O(?p5!vr%UXa9hKj;Z>+`RS?4(Q2MDk=*i|i0ilkopdUl7q2jkN+=TM^o z(TQ~Gc`mO4uZcn6X4s%|{yodLVu*WaI9}j;4v%V zbvp-e!7@1_*n{ehoPW^fAT2c?nX@C7vQ^!W5>4v(?ne$!U@^I_>9vCSD7xQ+fLdLm z!3F`myAPI+L>@VblgvSuXquY>2ZoM`^KvV4FKkFhdJGfR-+6q6#%W*IA}|~9gZV_j zyH)q4)s3Pvlt*B<`4?AKqg;uuL=lSx4gL<(j2{=AANSIfoW_SG0h%l|oS!7K2B<=0sD6)HD1EDfug7 zG6RO0S7@yb9|KB*y}K%we{SIV2j3|&?!vwx7GB6#1y^@x7a%Y-HQh|=+>lVHKZ1Av zhx!QjBYMQ;m8*G)?J~Y)qyg;1@LBSYV%@YWzoU1(-+|rzdfE{53DV_ZUY~_)fsN!( zM%#R{ZjDbV~1K9m!tw1iFsFx>*Z zdyaXbp2(cJOPdTJHknEBCB>T zsXrx!uQ-0^=z7B6xR}D%d{VO`V%3Z#xjEA*10)ckyP>lcz5TCtFlTX049&Y!45rZJRqlH0DV8zDozDQ0X=!@k1ZP~Ku4?<=uwfjGGWdS)^ zJy#i*C9tEuKaq?CZ56NXKz$3Qun73c&~!90UK3i<7u!)qSBF2I*88ug61Baz%gRs- z4uV(Yt45M%WcLA1ozYlwXqIxHw{Cmx(a_dM|*mxNpIbW1Xni%%cAN3x2$f9iF zydfE9Aqy6t$H%h{^Q8^T8k^Cp1@l0yfT?>pwK4fh)Co+$0zSl`#R!N#W-qwxc~&%B zh60cOrQ1KRCk&qTE*TTB$2|7gshVZ6tQ z&3d+v%J{1gMEKDQSp%+tk)C73OK6jQ!I#E)v51#R{@vUTW>T$V5Cl|IA~*YtZljE7FdqKnR9uUgr!Fmn1WuaL0nNOQscJOZqGahFL^Ev=}A&%*ISP{DR? zftVYl$o1wOll!Oqs^+OISPZ2%J2-6lLT!g%YF{tsjL=!~OQbh`0f>sex-~52f|&>f zV9_m%H#MMW0YA>j_!NVQc*B-J6Roxu>Rei%+hxInZL1~C_bJk8so?+3jg%*=0jl$Z zm3x!_G~+mQVQ{wvoKqs))|f?nfuNfT2%V)&y$#>kcNgxGgu6Z#`!MPGo94_Et!SdO zk@RYJa2C=v+nZ&DVp_}BsHNkU)v=S_L}BnO+$7(C1CiJM_6TNM-0BD#>YZ=<@}7FjgGFk4Tm{rwl81CkxRI`hJ~GmF zz95_*nLXfMHRfkhbsW1W4iaFgNvftKFUUYFsI#UHOp937QPnLUO2oF|X@MCg06w4`z2fkpcq(|NH* zz*9fbPeTDp`4_QB;oBA;!Qn1O4|z_35gk%)-+Vw{;ghZUfi4P&?wSn8xxAGF=C?w> zy+3MP6?rCq^GjE0;%k4D#&BJ)C3-3eYB^MF zV#6Z8nL!`hNB=13@=2&}0S5b{g84VTX9VGg&s>yV`3a;Z#ehBzFYwca+SaIf#_?9? zI9cpbib+g#0K7g=97e`#{!h{7%}hFPK?Jq!K>;+?5|wZcNuV+kf|jNP?Y~wcOAY8ZW;!8osdvz(SYFXwVTMpJX!c(!G)7q8B@ei7I+db@m^{eEC<0B|0+y}Wluq3}ki_KqIG`>Yj1 z17qprz?id3DbY4zcI-tgx=|mkk ze>Y-7nJYqA>xsuJzb1=q_8+buz060#EZf}6Sp@~|>6clC(8 z&11Zo#!v1zJ253y-l;elw4F=Z&}2F%FW9>8$Qb6M%qd(M=dyXW>NBRm6w%YJI=ahT zB<%|m58FoaDPa@_PS>@l;mFA5L3j1RIgLb^kcW)af;jfs0d@AIDToIlU~`#riJ zl@<3r=a^$$>X6GbK!(l{QKp2IaC zumx*lYI5?yNVUrzId>b#nC3xmQw$TjTCiv0f1PB#-2y`cAKez+O7f)@X#f5D_ileP zu5{dw&*8WJ0FcIZsWIY$=j{pp_e%^Q(&lN$0U1{!zzYkrKu$J zK<$D;1P5`a=7%-M65FzRC zO3F#XoA~TSwgEr9G`b0bNAm)hDx)Yq>$tbpgUkI)TF_r)Isk%!-3J8_1^RXDh9<)Q z{b@`wB0Q3@b|NT^8T5pR?g}i z9C}5sNoXDbS8Nas`uuabiwp1-fIQ0S=PRn+c3F_9q#ml6PRNtk4LhVFwjO8MFLM5z zeK6ixC^5#$b+nSeZ?JV~H(91k+?C8ERuvvlB4c5$Mr9Eio{V z%?ZA(PUD(9n%w}Z#ZW!GfJ`_k^^iRQx)@!UDOneLa$>p8t7q!f4AVPKpVzPeO;Z(6 z$g`bW1g1(4Sd=35fwP~*j<3}SS<*bHd+pe|C@+p!*6i(uH6y}#_0hN+otc^)|G7o- zdIsI>+>voed`!+=N66s(a4NPM$Y_)M8ABH z&cif6=fFGvZ);69WbX2gk+mk1^-I~1MEz?C!sVb%Xttu_^)y>N;%i0nokPH5eF}U-y1e9Z68^btEIUW@Dn$ZmO#oz|ODoQKd%4K(R`Ci^* znFEghSvaAZ45Qy=!lI%~feE<=nFvwP6}{>~uJ|Og3S4n@h|B5*7QBr5fadg=f5;{n zi|g;QJc4#2EIB|nszWKz);%;!~!iH)@!s<0~ou(O}Z zU-&Tz4d1F32GdLXzhX%^oN0&WErw!9k*i7{#!?o*T!$~iE*m> zh6Ttp#F`~s;Vc>`>d`fA6<&Flp$Li)p&Ckz`|5L$+7BG;Z-~|C7n}8QSNsZ693*&n z-n2V2?>lEj6PgCnW2SuW9*A^*h4XD7$>iHR10|N0Pv1X(9hI*SiG-_Z8*(h*d-xGk zLjkAVWH02eyX5XcAq{rbxsC`z#$e1Yr@@nJDuS)AcUc#u0Cdm4oXTFgJrTyCwGFjJ zQY`GX<`}nqhZ_BL&={h4HV?mVm^M{!&$2t=ih5w4mWgZg z!6#d%;(-?_-8>2juz_1GIm%&zTKU_qv1ANVyXgF25dWt5OGxj&$e#zvClg02E)Bf) zwdApQhXqSm+(I)+!I^f8!|U?}t^J^dA1lGb1jL}wzk`J9L4BYyHvp}5mCNpOJ&k80 z3jZivg-TIiAiaCP2Ori|DF9E0DBV=w$lJ4D@T>Z55d$PfiUxr+pY8m8loaf^kZeJ{ zbzwn$<;vU`kBH&IV3{i}1*|E`zg;61tzlD7>4hLZc z*x)=Lz(WSj_)b$6`&rh-_T;x~^L-tn+tW-N_5|;xYqMa0bD!wuC_W0bXg^x)kqXT} zgeMk`1USCRJ<|(Awgb(sTN6|nchZ80wP&7d=wL&Mt>|1gf6~Z?ULH*z8HFn7E5R`2 zhqLPp%Jl-c!j4SsGAj##_7xg2*UEtu)vTkb?m>5Z?e?KSEwFA8s2>>^w3=#())9Ch zk|1smb`$fR>bJ2T3#XND)WShLQM?CUZx%x(OUDYW8fM&>`Kf$c3%7AaK@on4qi} z_Y)fQzDbZq!N{&voT)gIt(r*W%;uePr-{ho8&aXm+Ri>ML_~MrGhMTMG{H=JJ1Iq`37^Fj=Yg^tolGVBC4 z2e{WX7SFIR@`Ybf(-D5&N_o}t?zx;|v5r_pNk(is@BX3JxB zsy!_E$oB*EtD$$|v{_OxCw&CRIAJc(92g5AeKDW?(nB~HaJ%;)zmsF#E5{SAXK<_3 zN4j*!;Xc0`W5>h8?z6q2^d2$Ec-W!q;Y2XcyR9~0llQ<#tHKtiZDQZ{ z1S~BUWM94Zqrq(%bJ}8(S-R~+!|tzn7aQxB!|>G~=%AEMdn=pkMNgHb+%~-|zjiaz zQR=((WYcqXP8bpM4Ots#_!Wx=x*S5V0UsdGB62?>E^(Sg*@n(RVc>(R4M;)@NANJ> zld5srY41W4Zcwm_fe2X#qmU^1xg(pss;t;pT7NpF69C z3_#AIQ_K^caVg_g+>zYnzbeoa_7h=Gk6;rx|D0k(UfQ?~!s@X#CxE?URZ#fmpXaF{lfu?sTxK5De-$&M;Su zyIC3e9{GVA#x zJsgg);`2on?J;uc>LJC*^=BkgwC(*w;4FzjQ7K4g%x62(vgt#hm-PVB3vI_O`8nRl zRUdZB*ZWO}xPd>Qc95EKrcEYk+eMx43>N&}-8;If(B9W?CR*j2I%?O}HPZ^cPLmC(q=rt7UX(G1^yxFW58&oZsAU{WIX-LxdBub@2D3_YvH zRH)!g=kwGSb{z*|jQDfKI`OhX^MP*OPTq83{mu`n*|pj0YW9RtoR>PXprqi8UV?OU zi1rJW_A?J+QDfvt>L2B#eT1X!!#8jeDvvAe|EoWCJ%06bf_u2~N!t+@JE|sEa5>Vp zr7D|Ai5e9Cj3B8*3EqQTwJI;XiG(eGUYR#|)`2mxYFA9N^$Eryr`3n?mCyX~xx2!$ zO^J3|*zGd|yNLAJGhX3!r{gDdF%gBZW6P?0OmZ@G9rw4UaB(k4`>&{Qw#|mfulckW z%VqF`!4a2+ST>YmRmZB%RPj}n1a{A@QDF5P!Ai4EVlTF_6przBua*;1>Mxl+#RZ5c z;ofa6@YF=hUY;gX-Eab%&Y}0VvxD-l1s`H5Q)MZo6Hhf!8^>+sNU;$}@qCH{O|mQ7 zT3RBDjtDq8*-nH)GcjDx0?wr_!&tE5sAIm1KOvL6+5nj2Gu+>vR8*I}>2Qz5%+;SM zNThqR93gsV%&FHbk-5S4zL@Q5%6J`9`%1@7c5yh~tayrIX!)gXJ6DLK7CNDq@9swW z5_O~R-LMb70)23D4;6nBBv0sKYnu(ezZSW!9xwT-ImWbb&1aq%^b4r8upPqowB-Qo z9QmWJYkRM|ZrtaBil1cNX;!^_eV?e?%91n7g&e=&Foa<~)aKdB^lhS3O%da=!bUbh zvW#B-lB5KUp~|=YyX4uMzonLKNhW4ULb@ry(W}a&pv4OD!1jP$B!2RG!?$nGzo%WK z!=IRS?>O;Nl*(89EmjrM^SblufNiL0rF8NBgd81nGJ-qIXgfiL0bGdX&C3I{`Wix9 z1XX?fWe6|)F!F*CYy-`1R0%eN3jU&?^)u~A@l|YP0j_=t$`F$G?hxH>j@^PXs>1xI zjac)mR0q+}mOK7!w7ttejC>OP1RIeKt^JINt{8z`ps-6!d`LD?$mxrKtYFlF1xcZr zoP3|_B3a1R@tY6jhch9 zPS?nK*v#D)M>l_c3q~M70ZOv~2cMONk=Tkjb+^IzQxk&KYGreI$Y;TqL2Nkr!2#rH zeD7F$jOLeY+#`FmYqe%TtuwFzNVE12;r{oNS`W(Mubm*Al?=FS3_S&NC9h~mO#+J6Skt7?kG1t=?9)RO{pv6?Qc7W9Pvfu}`v&fme zJ>qs?PA6#dEb$X)k<3wvJaCEVHM>0L+FTE~hbGH$83CYXCt=mLN3453VT+JLo@|IG zT|^(eVNeu|sfWA}Ceoj}ZrGGtY(CJB%1}rX*`WCP=W?e=Ig<6JO{UzJPN;i?U7)dv z8_b<*Le7dX)KMy`t9kr}hVM3czRoKm%0cNnUem?UC!Fb?+{Q30& z1Y~oe#mWMw_tiJfmyby$Ru{#35~YY-w#Rz=X~Cpbk`gd!*x{({#6?Q!%=DxxMNRf3 ze28)WeKVYS6cV%&c!eR~e)NnFFY#Hm*H4x1I)j~&nXP*Fr8U^;GhF!R;gN?Z+^dgR>WuLwN zI`$}~_kXID@*B5*L3!U?chSm}~UGdHt){*l~i-yuY*-{26QlXlyc?emqF6 zEjgdJek$Qe={ME_QJ-@yys?F^Ynck}rr%+kY1L$^=H=F8>j7YEuA7awLhTwd1}a8n z`p^A)TFh9S?1KT@0dp7Q@9GoQb6F+*_+-Kl!IcYaO}jPGKGF*7kG;vGcZ89%6Z&KN zP&sbZV+Zju0mcA&O&$CD3@s*WGj`0ju|3lxNI*cqwwbr5w_D5792zJeM0Vy2IKz;) zLfMVBOwEEpitlfxK;rrloiO~PY7)Ppg6=d3tA?^ydr7NayV5@I`@PI3Bk&3MAcXBe zuo}9?yJQRgfrW25%NwHIz-*_>q6VQ~MR3$+y)E)ru{BXTcpn?P*yz(R{NbWPsOR|h zg;$=x2#iTznvn*jlI!>;X4u~8yY>D?AmcywI^4tH=Qj-ypMDIyRgZxOX$>1IXZij4 zFQ;!8!pAlL?EReJ6Qy|UwI{FN(zw9Vu?6#kviY|DY>6;x7c{O@D^b=LAr1v#o;E}( zy7`bw57|uUoSAvzC-60khSwzIZkn1wa8rBZF_*5p8fA1h1s;^f2 zp2n70J*O#ht%|z+c&|w)OLKH2`ug7QZB<*(n%g|h3-4zZD~7+?F_@ckDYvR@ok+yX z`B@MXHXi-X1PsTMeoFW>y|u348H41 zJyFB_YY6)?L;6Jt(|k7T=j_`zk}LZBuk-mewp4ug>s>14F244fp4QiOIm+_2uOV0N zh!Q50v%!&t7UgG@3#Ty zZU&9^?gSaIVC^0pk37(}jy83*Cg?&Lt=+*Vih9wpz&mlyU%XFMA7zZb6)o81C$w+_ z;UuU}-g0C7uNnj5hKldyt0rdSdmon9=EMqOPI>7}_33<;jpEIolQXC>rn0-{G$>{< z8QpBQnyaK9R>M7`ZMH(qhOP`Bjer$!GK?2JM2qe91QB^+h%#xbIMJ$bsm^*gx! z1OIN@;Ey&B-LSfO>VxYMwoeP7r-wB&v6$XBtSXnjSrpUJAv%ydVrbahQfRx+TjTKj z<+w#qzR0t|kLqOAdawK&{&RGB%NqA!)d%H|ECbM}1(nAj?HC$E>S04t{2n~pP@&{I z?F!H|E-f`CpNR5usmputo3qdXoMF&;(qH(u_a3MSX%-G3?hGJo0+`#~{*X-Aq zkw=l*j%kLw?K1{y)#2{1mV*l~7q91@ zo!RUAC3?9c`iy-JhSBL|_A`P%0JZqK>Ut-%?i;y|U;@+KXTL z5Rzs73VQok`6tS{HU_O*U%vQ7Zpskfxd>@FslEq<(^gWERTVpf=9ec<&jaedtfltl z^_^eiSA6ff)3H*EzKJ0v-HDG_T?jDPo^1O2y@g8{E-|5qw`G~IO z@63-YmO|wfz9VKv_78QYdCf~-`Ct9B$i$y_XlFq8qN*v9_j@?GR2*%?LsZ07P_I|6 zv=l%h*0E4?;A$tMGTZ*aTyOA}-&)g<^BsqVs1gcr2vpWFHG3psmn>{a!)GCs8XcV` zQ2+VDx`Q1_LE9s1AC@VliW|==7sfxUR}gNFTiEOVxgD&OXxarlL3c9=ct;hn{mn!K zpRdCq(2trKfV-_}slA*0Jse9=MgEV{ir!1Dg_ka=NM!sgnEL^J1&w(f2*+xwq| z@CU}Qp1zR|shT;0wc{qDzm;T@rtY`4e%0D&Gv^mB5#)M*?tRVR2osxS^;mnF|N6`% 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

&YhG+53 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 PDb Date: Wed, 6 Oct 2021 11:32:49 +0200 Subject: [PATCH 23/27] Tests: Implement generic default options reachability test Tests: remove duplicate TestDeathMountain.py LttP: Move er_seeds out of Main OriBF: Fix Mapstone typo --- BaseClasses.py | 180 ++++++++++++++++++++--------- Generate.py | 2 +- Main.py | 23 +--- WebHostLib/generate.py | 2 +- test/Reachability.py | 32 +++++ test/TestDeathMountain.py | 38 ------ worlds/AutoWorld.py | 1 + worlds/alttp/EntranceRandomizer.py | 3 +- worlds/alttp/__init__.py | 12 +- worlds/oribf/RulesData.py | 2 +- 10 files changed, 169 insertions(+), 126 deletions(-) create mode 100644 test/Reachability.py delete mode 100644 test/TestDeathMountain.py diff --git a/BaseClasses.py b/BaseClasses.py index 6f9775b5..58009b6c 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -25,7 +25,6 @@ class MultiWorld(): plando_texts: List[Dict[str, str]] plando_items: List plando_connections: List - er_seeds: Dict[int, str] worlds: Dict[int, Any] is_race: bool = False @@ -66,15 +65,20 @@ class MultiWorld(): self.dynamic_regions = [] self.dynamic_locations = [] self.spoiler = Spoiler(self) - self.fix_trock_doors = self.AttributeProxy(lambda player: self.shuffle[player] != 'vanilla' or self.mode[player] == 'inverted') - self.fix_skullwoods_exit = self.AttributeProxy(lambda player: self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) - self.fix_palaceofdarkness_exit = self.AttributeProxy(lambda player: self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) - self.fix_trock_exit = self.AttributeProxy(lambda player: self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) + self.fix_trock_doors = self.AttributeProxy( + lambda player: self.shuffle[player] != 'vanilla' or self.mode[player] == 'inverted') + self.fix_skullwoods_exit = self.AttributeProxy( + lambda player: self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) + self.fix_palaceofdarkness_exit = self.AttributeProxy( + lambda player: self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) + self.fix_trock_exit = self.AttributeProxy( + lambda player: self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) self.NOTCURSED = self.AttributeProxy(lambda player: not self.CURSED[player]) for player in range(1, players + 1): def set_player_attr(attr, val): self.__dict__.setdefault(attr, {})[player] = val + set_player_attr('tech_tree_layout_prerequisites', {}) set_player_attr('_region_cache', {}) set_player_attr('shuffle', "vanilla") @@ -122,6 +126,17 @@ class MultiWorld(): set_player_attr('completion_condition', lambda state: True) self.custom_data = {} self.worlds = {} + self.slot_seeds = {} + + def set_seed(self, seed: Optional[int] = None, secure: bool = False, name: Optional[str] = None): + self.seed = get_seed(seed) + if secure: + self.secure() + else: + self.random.seed(self.seed) + self.seed_name = name if name else str(self.seed) + self.slot_seeds = {player: random.Random(self.random.getrandbits(64)) for player in + range(1, self.players + 1)} def set_options(self, args): from worlds import AutoWorld @@ -230,7 +245,7 @@ class MultiWorld(): if item.name in subworld.dungeon_local_item_names: subworld.collect(ret, item) ret.sweep_for_events() - + if use_cache: self._all_state = ret return ret @@ -270,7 +285,7 @@ class MultiWorld(): else: raise RuntimeError('Cannot assign item %s to location %s.' % (item, location)) - def get_entrances(self) -> list: + def get_entrances(self) -> List[Entrance]: if self._cached_entrances is None: self._cached_entrances = [entrance for region in self.regions for entrance in region.entrances] return self._cached_entrances @@ -278,7 +293,7 @@ class MultiWorld(): def clear_entrance_cache(self): self._cached_entrances = None - def get_locations(self) -> list: + def get_locations(self) -> List[Location]: if self._cached_locations is None: self._cached_locations = [location for region in self.regions for location in region.locations] return self._cached_locations @@ -286,7 +301,7 @@ class MultiWorld(): def clear_location_cache(self): self._cached_locations = None - def get_unfilled_locations(self, player=None) -> list: + def get_unfilled_locations(self, player=None) -> List[Location]: if player is not None: return [location for location in self.get_locations() if location.player == player and not location.item] @@ -295,19 +310,19 @@ class MultiWorld(): def get_unfilled_dungeon_locations(self): return [location for location in self.get_locations() if not location.item and location.parent_region.dungeon] - def get_filled_locations(self, player=None) -> list: + def get_filled_locations(self, player=None) -> List[Location]: if player is not None: return [location for location in self.get_locations() if location.player == player and location.item is not None] return [location for location in self.get_locations() if location.item is not None] - def get_reachable_locations(self, state=None, player=None) -> list: + def get_reachable_locations(self, state=None, player=None) -> List[Location]: if state is None: state = self.state return [location for location in self.get_locations() if (player is None or location.player == player) and location.can_reach(state)] - def get_placeable_locations(self, state=None, player=None) -> list: + def get_placeable_locations(self, state=None, player=None) -> List[Location]: if state is None: state = self.state return [location for location in self.get_locations() if @@ -335,7 +350,7 @@ class MultiWorld(): else: return all((self.has_beaten_game(state, p) for p in range(1, self.players + 1))) - def can_beat_game(self, starting_state : Optional[CollectionState]=None): + def can_beat_game(self, starting_state: Optional[CollectionState] = None): if starting_state: if self.has_beaten_game(starting_state): return True @@ -392,7 +407,7 @@ class MultiWorld(): """Check if accessibility rules are fulfilled with current or supplied state.""" if not state: state = CollectionState(self) - players = {"minimal" : set(), + players = {"minimal": set(), "items": set(), "locations": set()} for player, access in self.accessibility.items(): @@ -400,13 +415,13 @@ class MultiWorld(): beatable_fulfilled = False - def location_conditition(location : Location): + def location_conditition(location: Location): """Determine if this location has to be accessible, location is already filtered by location_relevant""" if location.player in players["minimal"]: return False return True - def location_relevant(location : Location): + def location_relevant(location: Location): """Determine if this location is relevant to sweep.""" if location.player in players["locations"] or location.event or \ (location.item and location.item.advancement): @@ -499,7 +514,8 @@ class CollectionState(object): ret.prog_items = self.prog_items.copy() ret.reachable_regions = {player: copy.copy(self.reachable_regions[player]) for player in range(1, self.world.players + 1)} - ret.blocked_connections = {player: copy.copy(self.blocked_connections[player]) for player in range(1, self.world.players + 1)} + ret.blocked_connections = {player: copy.copy(self.blocked_connections[player]) for player in + range(1, self.world.players + 1)} ret.events = copy.copy(self.events) ret.path = copy.copy(self.path) ret.locations_checked = copy.copy(self.locations_checked) @@ -535,10 +551,10 @@ class CollectionState(object): def has(self, item, player: int, count: int = 1): return self.prog_items[item, player] >= count - def has_all(self, items: Set[str], player:int): + def has_all(self, items: Set[str], player: int): return all(self.prog_items[item, player] for item in items) - def has_any(self, items: Set[str], player:int): + def has_any(self, items: Set[str], player: int): return any(self.prog_items[item, player] for item in items) def has_group(self, item_name_group: str, player: int, count: int = 1): @@ -638,10 +654,10 @@ class CollectionState(object): self.is_not_bunny(cave, player) ) - def can_retrieve_tablet(self, player:int) -> bool: + def can_retrieve_tablet(self, player: int) -> bool: return self.has('Book of Mudora', player) and (self.has_beam_sword(player) or - (self.world.swordless[player] and - self.has("Hammer", player))) + (self.world.swordless[player] and + self.has("Hammer", player))) def has_sword(self, player: int) -> bool: return self.has('Fighter Sword', player) \ @@ -650,7 +666,8 @@ class CollectionState(object): or self.has('Golden Sword', player) def has_beam_sword(self, player: int) -> bool: - return self.has('Master Sword', player) or self.has('Tempered Sword', player) or self.has('Golden Sword', player) + return self.has('Master Sword', player) or self.has('Tempered Sword', player) or self.has('Golden Sword', + player) def has_melee_weapon(self, player: int) -> bool: return self.has_sword(player) or self.has('Hammer', player) @@ -714,7 +731,7 @@ class CollectionState(object): rules.append(self.has('Moon Pearl', player)) return all(rules) - def can_bomb_clip(self, region: Region, player: int) -> bool: + def can_bomb_clip(self, region: Region, player: int) -> bool: return self.is_not_bunny(region, player) and self.has('Pegasus Boots', player) def collect(self, item: Item, event: bool = False, location: Location = None) -> bool: @@ -742,12 +759,13 @@ class CollectionState(object): self.blocked_connections[item.player] = set() self.stale[item.player] = True + @unique class RegionType(int, Enum): Generic = 0 LightWorld = 1 DarkWorld = 2 - Cave = 3 # Also includes Houses + Cave = 3 # Also includes Houses Dungeon = 4 @property @@ -869,6 +887,7 @@ class Dungeon(object): def __str__(self): return self.world.get_name_string_for_object(self) if self.world else f'{self.name} (Player {self.player})' + class Boss(): def __init__(self, name, enemizer_name, defeat_rule, player: int): self.name = name @@ -882,6 +901,7 @@ class Boss(): def __repr__(self): return f"Boss({self.name})" + class Location(): # If given as integer, then this is the shop's inventory index shop_slot: Optional[int] = None @@ -897,7 +917,7 @@ class Location(): access_rule = staticmethod(lambda state: True) item_rule = staticmethod(lambda item: True) - def __init__(self, player: int, name: str = '', address:int = None, parent=None): + def __init__(self, player: int, name: str = '', address: int = None, parent=None): self.name: str = name self.address: Optional[int] = address self.parent_region: Region = parent @@ -1021,39 +1041,58 @@ class Spoiler(): def set_entrance(self, entrance, exit, direction, player): if self.world.players == 1: - self.entrances[(entrance, direction, player)] = OrderedDict([('entrance', entrance), ('exit', exit), ('direction', direction)]) + self.entrances[(entrance, direction, player)] = OrderedDict( + [('entrance', entrance), ('exit', exit), ('direction', direction)]) else: - self.entrances[(entrance, direction, player)] = OrderedDict([('player', player), ('entrance', entrance), ('exit', exit), ('direction', direction)]) + self.entrances[(entrance, direction, player)] = OrderedDict( + [('player', player), ('entrance', entrance), ('exit', exit), ('direction', direction)]) def parse_data(self): self.medallions = OrderedDict() for player in self.world.get_game_players("A Link to the Past"): - self.medallions[f'Misery Mire ({self.world.get_player_name(player)})'] = self.world.required_medallions[player][0] - self.medallions[f'Turtle Rock ({self.world.get_player_name(player)})'] = self.world.required_medallions[player][1] + self.medallions[f'Misery Mire ({self.world.get_player_name(player)})'] = \ + self.world.required_medallions[player][0] + self.medallions[f'Turtle Rock ({self.world.get_player_name(player)})'] = \ + self.world.required_medallions[player][1] self.locations = OrderedDict() listed_locations = set() - lw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.LightWorld and loc.show_in_spoiler] - self.locations['Light World'] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in lw_locations]) + lw_locations = [loc for loc in self.world.get_locations() if + loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.LightWorld and loc.show_in_spoiler] + self.locations['Light World'] = OrderedDict( + [(str(location), str(location.item) if location.item is not None else 'Nothing') for location in + lw_locations]) listed_locations.update(lw_locations) - dw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.DarkWorld and loc.show_in_spoiler] - self.locations['Dark World'] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in dw_locations]) + dw_locations = [loc for loc in self.world.get_locations() if + loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.DarkWorld and loc.show_in_spoiler] + self.locations['Dark World'] = OrderedDict( + [(str(location), str(location.item) if location.item is not None else 'Nothing') for location in + dw_locations]) listed_locations.update(dw_locations) - cave_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.Cave and loc.show_in_spoiler] - self.locations['Caves'] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in cave_locations]) + cave_locations = [loc for loc in self.world.get_locations() if + loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.Cave and loc.show_in_spoiler] + self.locations['Caves'] = OrderedDict( + [(str(location), str(location.item) if location.item is not None else 'Nothing') for location in + cave_locations]) listed_locations.update(cave_locations) for dungeon in self.world.dungeons.values(): - dungeon_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.dungeon == dungeon and loc.show_in_spoiler] - self.locations[str(dungeon)] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in dungeon_locations]) + dungeon_locations = [loc for loc in self.world.get_locations() if + loc not in listed_locations and loc.parent_region and loc.parent_region.dungeon == dungeon and loc.show_in_spoiler] + self.locations[str(dungeon)] = OrderedDict( + [(str(location), str(location.item) if location.item is not None else 'Nothing') for location in + dungeon_locations]) listed_locations.update(dungeon_locations) - other_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.show_in_spoiler] + other_locations = [loc for loc in self.world.get_locations() if + loc not in listed_locations and loc.show_in_spoiler] if other_locations: - self.locations['Other Locations'] = OrderedDict([(str(location), str(location.item) if location.item is not None else 'Nothing') for location in other_locations]) + self.locations['Other Locations'] = OrderedDict( + [(str(location), str(location.item) if location.item is not None else 'Nothing') for location in + other_locations]) listed_locations.update(other_locations) self.shops = [] @@ -1069,10 +1108,13 @@ class Spoiler(): if item is None: continue my_price = item['price'] // price_rate_display.get(item['price_type'], 1) - shopdata['item_{}'.format(index)] = f"{item['item']} — {my_price} {price_type_display_name[item['price_type']]}" + shopdata['item_{}'.format( + index)] = f"{item['item']} — {my_price} {price_type_display_name[item['price_type']]}" if item['player'] > 0: - shopdata['item_{}'.format(index)] = shopdata['item_{}'.format(index)].replace('—', '(Player {}) — '.format(item['player'])) + shopdata['item_{}'.format(index)] = shopdata['item_{}'.format(index)].replace('—', + '(Player {}) — '.format( + item['player'])) if item['max'] == 0: continue @@ -1080,7 +1122,8 @@ class Spoiler(): if item['replacement'] is None: continue - shopdata['item_{}'.format(index)] += f", {item['replacement']} - {item['replacement_price']} {price_type_display_name[item['replacement_price_type']]}" + shopdata['item_{}'.format( + index)] += f", {item['replacement']} - {item['replacement_price']} {price_type_display_name[item['replacement_price_type']]}" self.shops.append(shopdata) for player in self.world.get_game_players("A Link to the Past"): @@ -1089,7 +1132,8 @@ class Spoiler(): self.bosses[str(player)]["Desert Palace"] = self.world.get_dungeon("Desert Palace", player).boss.name self.bosses[str(player)]["Tower Of Hera"] = self.world.get_dungeon("Tower of Hera", player).boss.name self.bosses[str(player)]["Hyrule Castle"] = "Agahnim" - self.bosses[str(player)]["Palace Of Darkness"] = self.world.get_dungeon("Palace of Darkness", player).boss.name + self.bosses[str(player)]["Palace Of Darkness"] = self.world.get_dungeon("Palace of Darkness", + player).boss.name self.bosses[str(player)]["Swamp Palace"] = self.world.get_dungeon("Swamp Palace", player).boss.name self.bosses[str(player)]["Skull Woods"] = self.world.get_dungeon("Skull Woods", player).boss.name self.bosses[str(player)]["Thieves Town"] = self.world.get_dungeon("Thieves Town", player).boss.name @@ -1097,13 +1141,19 @@ class Spoiler(): self.bosses[str(player)]["Misery Mire"] = self.world.get_dungeon("Misery Mire", player).boss.name self.bosses[str(player)]["Turtle Rock"] = self.world.get_dungeon("Turtle Rock", player).boss.name if self.world.mode[player] != 'inverted': - self.bosses[str(player)]["Ganons Tower Basement"] = self.world.get_dungeon('Ganons Tower', player).bosses['bottom'].name - self.bosses[str(player)]["Ganons Tower Middle"] = self.world.get_dungeon('Ganons Tower', player).bosses['middle'].name - self.bosses[str(player)]["Ganons Tower Top"] = self.world.get_dungeon('Ganons Tower', player).bosses['top'].name + self.bosses[str(player)]["Ganons Tower Basement"] = \ + self.world.get_dungeon('Ganons Tower', player).bosses['bottom'].name + self.bosses[str(player)]["Ganons Tower Middle"] = self.world.get_dungeon('Ganons Tower', player).bosses[ + 'middle'].name + self.bosses[str(player)]["Ganons Tower Top"] = self.world.get_dungeon('Ganons Tower', player).bosses[ + 'top'].name else: - self.bosses[str(player)]["Ganons Tower Basement"] = self.world.get_dungeon('Inverted Ganons Tower', player).bosses['bottom'].name - self.bosses[str(player)]["Ganons Tower Middle"] = self.world.get_dungeon('Inverted Ganons Tower', player).bosses['middle'].name - self.bosses[str(player)]["Ganons Tower Top"] = self.world.get_dungeon('Inverted Ganons Tower', player).bosses['top'].name + self.bosses[str(player)]["Ganons Tower Basement"] = \ + self.world.get_dungeon('Inverted Ganons Tower', player).bosses['bottom'].name + self.bosses[str(player)]["Ganons Tower Middle"] = \ + self.world.get_dungeon('Inverted Ganons Tower', player).bosses['middle'].name + self.bosses[str(player)]["Ganons Tower Top"] = \ + self.world.get_dungeon('Inverted Ganons Tower', player).bosses['top'].name self.bosses[str(player)]["Ganons Tower"] = "Agahnim 2" self.bosses[str(player)]["Ganon"] = "Ganon" @@ -1217,22 +1267,30 @@ class Spoiler(): outfile.write(f"\n{recipe.name} ({name}): {recipe.ingredients} -> {recipe.products}") outfile.write('\n\nLocations:\n\n') - outfile.write('\n'.join(['%s: %s' % (location, item) for grouping in self.locations.values() for (location, item) in grouping.items()])) + outfile.write('\n'.join( + ['%s: %s' % (location, item) for grouping in self.locations.values() for (location, item) in + grouping.items()])) if self.shops: outfile.write('\n\nShops:\n\n') - outfile.write('\n'.join("{} [{}]\n {}".format(shop['location'], shop['type'], "\n ".join(item for item in [shop.get('item_0', None), shop.get('item_1', None), shop.get('item_2', None)] if item)) for shop in self.shops)) + outfile.write('\n'.join("{} [{}]\n {}".format(shop['location'], shop['type'], "\n ".join( + item for item in [shop.get('item_0', None), shop.get('item_1', None), shop.get('item_2', None)] if + item)) for shop in self.shops)) for player in self.world.get_game_players("A Link to the Past"): if self.world.boss_shuffle[player] != 'none': bossmap = self.bosses[str(player)] if self.world.players > 1 else self.bosses - outfile.write(f'\n\nBosses{(f" ({self.world.get_player_name(player)})" if self.world.players > 1 else "")}:\n') - outfile.write(' '+'\n '.join([f'{x}: {y}' for x, y in bossmap.items()])) + outfile.write( + f'\n\nBosses{(f" ({self.world.get_player_name(player)})" if self.world.players > 1 else "")}:\n') + outfile.write(' ' + '\n '.join([f'{x}: {y}' for x, y in bossmap.items()])) outfile.write('\n\nPlaythrough:\n\n') - outfile.write('\n'.join(['%s: {\n%s\n}' % (sphere_nr, '\n'.join([' %s: %s' % (location, item) for (location, item) in sphere.items()] if sphere_nr != '0' else [f' {item}' for item in sphere])) for (sphere_nr, sphere) in self.playthrough.items()])) + outfile.write('\n'.join(['%s: {\n%s\n}' % (sphere_nr, '\n'.join( + [' %s: %s' % (location, item) for (location, item) in sphere.items()] if sphere_nr != '0' else [ + f' {item}' for item in sphere])) for (sphere_nr, sphere) in self.playthrough.items()])) if self.unreachables: outfile.write('\n\nUnreachable Items:\n\n') - outfile.write('\n'.join(['%s: %s' % (unreachable.item, unreachable) for unreachable in self.unreachables])) + outfile.write( + '\n'.join(['%s: %s' % (unreachable.item, unreachable) for unreachable in self.unreachables])) if self.paths: outfile.write('\n\nPaths:\n\n') @@ -1247,3 +1305,13 @@ class Spoiler(): path_listings.append("{}\n {}".format(location, "\n => ".join(path_lines))) outfile.write('\n'.join(path_listings)) + + +seeddigits = 20 + + +def get_seed(seed=None): + if seed is None: + random.seed(None) + return random.randint(0, pow(10, seeddigits) - 1) + return seed diff --git a/Generate.py b/Generate.py index 77fef3ac..797b35ee 100644 --- a/Generate.py +++ b/Generate.py @@ -17,7 +17,7 @@ from worlds.generic import PlandoItem, PlandoConnection from Utils import parse_yaml, version_tuple, __version__, tuplize_version, get_options from worlds.alttp.EntranceRandomizer import parse_arguments from Main import main as ERmain -from Main import get_seed, seeddigits +from BaseClasses import seeddigits, get_seed import Options from worlds.alttp import Bosses from worlds.alttp.Text import TextTable diff --git a/Main.py b/Main.py index f02aa155..389c8b25 100644 --- a/Main.py +++ b/Main.py @@ -1,7 +1,6 @@ from itertools import zip_longest import logging import os -import random import time import zlib import concurrent.futures @@ -19,15 +18,6 @@ from Utils import output_path, get_options, __version__, version_tuple from worlds.generic.Rules import locality_rules, exclusion_rules from worlds import AutoWorld -seeddigits = 20 - - -def get_seed(seed=None): - if seed is None: - random.seed(None) - return random.randint(0, pow(10, seeddigits) - 1) - return seed - def main(args, seed=None): if args.outputpath: @@ -39,13 +29,8 @@ def main(args, seed=None): # initialize the world world = MultiWorld(args.multi) - logger = logging.getLogger('') - world.seed = get_seed(seed) - if args.race: - world.secure() - else: - world.random.seed(world.seed) - world.seed_name = str(args.outputname if args.outputname else world.seed) + logger = logging.getLogger() + world.set_seed(args.race, str(args.outputname if args.outputname else world.seed)) world.shuffle = args.shuffle.copy() world.logic = args.logic.copy() @@ -81,7 +66,6 @@ def main(args, seed=None): world.plando_items = args.plando_items.copy() world.plando_texts = args.plando_texts.copy() world.plando_connections = args.plando_connections.copy() - world.er_seeds = getattr(args, "er_seeds", {}) world.required_medallions = args.required_medallions.copy() world.game = args.game.copy() world.set_options(args) @@ -90,9 +74,6 @@ def main(args, seed=None): world.sprite = args.sprite.copy() world.glitch_triforce = args.glitch_triforce # This is enabled/disabled globally, no per player option. - world.slot_seeds = {player: random.Random(world.random.getrandbits(64)) for player in - range(1, world.players + 1)} - logger.info('Archipelago Version %s - Seed: %s\n', __version__, world.seed) logger.info("Found World Types:") diff --git a/WebHostLib/generate.py b/WebHostLib/generate.py index 23b013cc..60251ca3 100644 --- a/WebHostLib/generate.py +++ b/WebHostLib/generate.py @@ -9,7 +9,7 @@ from flask import request, flash, redirect, url_for, session, render_template from worlds.alttp.EntranceRandomizer import parse_arguments from Main import main as ERmain -from Main import get_seed, seeddigits +from BaseClasses import seeddigits, get_seed from Generate import handle_name import pickle diff --git a/test/Reachability.py b/test/Reachability.py new file mode 100644 index 00000000..31226822 --- /dev/null +++ b/test/Reachability.py @@ -0,0 +1,32 @@ +import unittest +from argparse import Namespace +from BaseClasses import MultiWorld +from worlds.AutoWorld import AutoWorldRegister, call_all + + +class TestBase(unittest.TestCase): + _state_cache = {} + gen_steps = ["generate_early", "create_regions", "create_items", "set_rules", "generate_basic", "pre_fill"] + + def testAllStateCanReachEverything(self): + for game_name, world_type in AutoWorldRegister.world_types.items(): + if game_name != "Ori and the Blind Forest": # TODO: fix Ori Logic + with self.subTest("Game", game=game_name): + + world = MultiWorld(1) + world.game[1] = game_name + world.player_name = {1: "Tester"} + world.set_seed() + args = Namespace() + for name, option in world_type.options.items(): + setattr(args, name, {1: option.from_any(option.default)}) + world.set_options(args) + world.set_default_common_options() + for step in self.gen_steps: + call_all(world, step) + state = world.get_all_state(False) + for location in world.get_locations(): + with self.subTest("Location should be reached", location=location): + if not location.can_reach(state): + print("Bla!") + self.assertTrue(location.can_reach(state)) diff --git a/test/TestDeathMountain.py b/test/TestDeathMountain.py deleted file mode 100644 index 43fffa40..00000000 --- a/test/TestDeathMountain.py +++ /dev/null @@ -1,38 +0,0 @@ -from test.vanilla.TestVanilla import TestVanilla - - -class TestDeathMountain(TestVanilla): - - def testWestDeathMountain(self): - self.run_location_tests([ - ["Ether Tablet", False, []], - ["Ether Tablet", False, [], ['Progressive Glove', 'Flute']], - ["Ether Tablet", False, [], ['Lamp', 'Flute']], - ["Ether Tablet", False, [], ['Magic Mirror', 'Hookshot']], - ["Ether Tablet", False, [], ['Magic Mirror', 'Hammer']], - ["Ether Tablet", False, ['Progressive Sword'], ['Progressive Sword']], - ["Ether Tablet", False, [], ['Book of Mudora']], - ["Ether Tablet", True, ['Flute', 'Magic Mirror', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']], - ["Ether Tablet", True, ['Progressive Glove', 'Lamp', 'Magic Mirror', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']], - ["Ether Tablet", True, ['Flute', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']], - ["Ether Tablet", True, ['Progressive Glove', 'Lamp', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']], - - ["Old Man", False, []], - ["Old Man", False, [], ['Progressive Glove', 'Flute']], - ["Old Man", False, [], ['Lamp']], - ["Old Man", True, ['Flute', 'Lamp']], - ["Old Man", True, ['Progressive Glove', 'Lamp']], - - ["Spectacle Rock Cave", False, []], - ["Spectacle Rock Cave", False, [], ['Progressive Glove', 'Flute']], - ["Spectacle Rock Cave", False, [], ['Lamp', 'Flute']], - ["Spectacle Rock Cave", True, ['Flute']], - ["Spectacle Rock Cave", True, ['Progressive Glove', 'Lamp']], - - ["Spectacle Rock", False, []], - ["Spectacle Rock", False, [], ['Progressive Glove', 'Flute']], - ["Spectacle Rock", False, [], ['Lamp', 'Flute']], - ["Spectacle Rock", False, [], ['Magic Mirror']], - ["Spectacle Rock", True, ['Flute', 'Magic Mirror']], - ["Spectacle Rock", True, ['Progressive Glove', 'Lamp', 'Magic Mirror']], - ]) diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 04d8c06a..bf48fd97 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -48,6 +48,7 @@ def call_all(world: MultiWorld, method_name: str, *args): for player in world.player_ids: world_types.add(world.worlds[player].__class__) call_single(world, method_name, player, *args) + for world_type in world_types: stage_callable = getattr(world_type, f"stage_{method_name}", None) if stage_callable: diff --git a/worlds/alttp/EntranceRandomizer.py b/worlds/alttp/EntranceRandomizer.py index c5053335..856ca611 100644 --- a/worlds/alttp/EntranceRandomizer.py +++ b/worlds/alttp/EntranceRandomizer.py @@ -257,7 +257,6 @@ def parse_arguments(argv, no_defaults=False): ret.plando_items = [] ret.plando_texts = {} ret.plando_connections = [] - ret.er_seeds = {} if ret.timer == "none": ret.timer = False @@ -280,7 +279,7 @@ def parse_arguments(argv, no_defaults=False): "triforce_pieces_available", "triforce_pieces_required", "shop_shuffle", "required_medallions", - "plando_items", "plando_texts", "plando_connections", "er_seeds", + "plando_items", "plando_texts", "plando_connections", 'dungeon_counters', 'shuffle_prizes', 'sprite_pool', 'dark_room_logic', 'game']: diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index 2011e177..47aad525 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -60,20 +60,20 @@ class ALTTPWorld(World): world = self.world # system for sharing ER layouts - world.er_seeds[player] = str(world.random.randint(0, 2 ** 64)) + self.er_seed = str(world.random.randint(0, 2 ** 64)) if "-" in world.shuffle[player]: shuffle, seed = world.shuffle[player].split("-", 1) world.shuffle[player] = shuffle if shuffle == "vanilla": - world.er_seeds[player] = "vanilla" + self.er_seed = "vanilla" elif seed.startswith("group-") or world.is_race: - world.er_seeds[player] = get_same_seed(world, ( + self.er_seed = get_same_seed(world, ( shuffle, seed, world.retro[player], world.mode[player], world.logic[player])) else: # not a race or group seed, use set seed as is. - world.er_seeds[player] = seed + self.er_seed = seed elif world.shuffle[player] == "vanilla": - world.er_seeds[player] = "vanilla" + self.er_seed = "vanilla" for dungeon_item in ["smallkey_shuffle", "bigkey_shuffle", "compass_shuffle", "map_shuffle"]: option = getattr(world, dungeon_item)[player] if option == "own_world": @@ -118,7 +118,7 @@ class ALTTPWorld(World): # seeded entrance shuffle old_random = world.random - world.random = random.Random(world.er_seeds[player]) + world.random = random.Random(self.er_seed) if world.mode[player] != 'inverted': link_entrances(world, player) diff --git a/worlds/oribf/RulesData.py b/worlds/oribf/RulesData.py index cffa494b..11a51c07 100644 --- a/worlds/oribf/RulesData.py +++ b/worlds/oribf/RulesData.py @@ -2,5 +2,5 @@ # do not edit manually # Rules from areas.ori -location_rules = {'casual-core': {'AboveChargeJumpAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'BashSkillTree': {frozenset({'GinsoKey'})}, 'BashAreaExp': {frozenset({'Bash', 'GinsoKey'}), frozenset({'GinsoKey', 'ChargeJump'})}, 'DashAreaOrbRoomExp': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DashAreaAbilityCell': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DashAreaRoofExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'BlackrootBoulderExp': {frozenset({'Stomp'})}, 'BlackrootMap': {frozenset({'Mapstone', 'ChargeJump'}), frozenset({'Climb', 'Mapstone', 'DoubleJump'}), frozenset({'Mapstone', 'WallJump'}), frozenset({'Grenade', 'Bash', 'Mapstone'})}, 'ChargeFlameAreaPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'DashAreaMapstone': {frozenset({'Dash'})}, 'DashAreaPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'DeathGauntletExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DeathGauntletStompSwim': {frozenset({'Stomp', 'Water'})}, 'DeathGauntletEnergyCell': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DeathGauntletSwimEnergyDoor': {frozenset({('EC', 4)})}, 'DeathGauntletRoofPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'DoubleJumpSkillTree': {frozenset({'Glide'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'Bash', 'Grenade'}), frozenset({'DoubleJump'})}, 'DoubleJumpAreaExp': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Climb', 'Bash', 'Grenade'}), frozenset({'Bash', 'WallJump', 'Water'}), frozenset({'ChargeJump', 'WallJump', 'Water'})}, 'ForlornHiddenSpiderExp': {frozenset({'ForlornKey', 'ChargeJump'}), frozenset({'ForlornKey', 'Bash'})}, 'ForlornKeystone1': {frozenset({'ForlornKey', 'ChargeJump'}), frozenset({'ForlornKey'}), frozenset({'Grenade', 'ForlornKey', 'Bash'}), frozenset({'ForlornKey', 'DoubleJump', 'Bash'})}, 'ForlornKeystone2': {frozenset({'ForlornKey', 'ChargeJump'}), frozenset({'Grenade', 'ForlornKey', 'Bash'}), frozenset({'Glide', 'ForlornKey', 'DoubleJump', 'WallJump'}), frozenset({'ForlornKey'}), frozenset({'Climb', 'ForlornKey', 'Glide', 'DoubleJump'})}, 'ForlornEntranceExp': {frozenset({'Grenade', 'ForlornKey', 'Bash'}), frozenset({'ForlornKey', 'ChargeJump', 'Open'}), frozenset({'ForlornKey', 'ChargeJump', 'DoubleJump'}), frozenset({'ForlornKey', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'ForlornKey', 'WallJump', 'Open'}), frozenset({'ForlornKey', 'DoubleJump', 'Open'}), frozenset({'Climb', 'ForlornKey', 'DoubleJump'}), frozenset({'ForlornKey', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'ForlornKey', 'ChargeJump'}), frozenset({'Glide', 'ForlornKey', 'Climb', 'Open'})}, 'ForlornEscape': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'ForlornMap': {frozenset({'ForlornKey', 'Mapstone'})}, 'ForlornKeystone4': {frozenset({'ForlornKey'}), frozenset({'Grenade', 'ForlornKey', 'WallJump', 'Bash'}), frozenset({'ForlornKey', 'ChargeJump', 'WallJump'}), frozenset({'Grenade', 'ForlornKey', 'Climb', 'Bash'}), frozenset({'Climb', 'ForlornKey', 'ChargeJump'})}, 'ForlornKeystone3': {frozenset({'Grenade', 'ForlornKey', 'Climb', 'Bash'}), frozenset({'Glide', 'ForlornKey', 'ChargeJump'}), frozenset({'ForlornKey'}), frozenset({'ForlornKey', 'ChargeJump', 'DoubleJump'})}, 'ForlornPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'LowerGinsoKeystone1': {frozenset({'DoubleJump'}), frozenset({'Glide'})}, 'LowerGinsoKeystone2': {frozenset({'DoubleJump'}), frozenset({'Glide'})}, 'LowerGinsoKeystone3': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'LowerGinsoKeystone4': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'GladesLaser': {frozenset({'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'GladesLaserGrenade': {frozenset({'Grenade', 'Climb', 'ChargeJump', 'Bash'}), frozenset({'Grenade', 'Bash', 'DoubleJump', 'WallJump'})}, 'GladesMap': {frozenset({'Mapstone'})}, 'GrenadeSkillTree': {frozenset({'Climb', 'Dash'}), frozenset({'Grenade', 'Dash', 'Bash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Dash', 'ChargeJump'})}, 'GrenadeAreaExp': {frozenset({'Climb', 'Dash', 'Glide'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide', 'Dash', 'Bash'}), frozenset({'Glide', 'Dash', 'WallJump'})}, 'GrenadeAreaAbilityCell': {frozenset({'Grenade', 'Dash', 'Bash'}), frozenset({'Grenade', 'Dash', 'ChargeJump'})}, 'GumoHideoutMap': {frozenset({'Mapstone'})}, 'GumoHideoutRightHangingExp': {frozenset({'Glide', 'Wind'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'Glide'}), frozenset({'ChargeJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Glide', 'WallJump'})}, 'GumoHideoutMapstone': {frozenset({'Glide'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'Bash', 'Grenade'}), frozenset({'DoubleJump'})}, 'GumoHideoutMiniboss': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'GumoHideoutEnergyCell': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'GumoHideoutCrusherExp': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'GumoHideoutCrusherKeystone': {frozenset({'Climb'}), frozenset({'WallJump'})}, 'GumoHideoutRedirectAbilityCell': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Glide'})}, 'GumoHideoutRedirectPlant': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'ChargeFlame'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Climb', 'Grenade'})}, 'GumoHideoutRedirectEnergyCell': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'Glide'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'DoubleJump'})}, 'GumoHideoutRedirectExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'Glide'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'DoubleJump'})}, 'GroveWaterStompAbilityCell': {frozenset({'Stomp', 'Water'})}, 'HoruFieldsHealthCell': {frozenset({'Stomp'})}, 'HollowGroveTreePlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'HollowGroveTreeAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Glide', 'Wind'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'HollowGroveMap': {frozenset({'Mapstone'})}, 'HollowGroveMapPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'SwampTeleporterAbilityCell': {frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash', 'Glide', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Glide', 'WallJump'}), frozenset({'Climb', 'Glide', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb', 'Glide'}), frozenset({'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'DoorWarpExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'HoruFieldsPlant': {frozenset({'Grenade', 'Glide', 'ChargeJump'}), frozenset({'ChargeFlame', 'Glide', 'ChargeJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'ChargeFlame', 'Bash'}), frozenset({'Climb', 'ChargeJump', 'Grenade'}), frozenset({'Climb', 'ChargeJump', 'ChargeFlame'})}, 'HoruFieldsEnergyCell': {frozenset({'Glide', 'Bash'}), frozenset({'Glide', 'ChargeJump', 'DoubleJump'}), frozenset({'Bash', 'DoubleJump'})}, 'HoruFieldsHiddenExp': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'HoruFieldsAbilityCell': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump'})}, 'HoruLavaDrainedLeftExp': {frozenset({'Open', 'Bash'}), frozenset({'Glide', 'Open', 'DoubleJump'}), frozenset({'Open', 'ChargeJump'})}, 'HoruLavaDrainedRightExp': {frozenset({'Glide', 'Open', 'Bash'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'}), frozenset({'Grenade', 'Open', 'Bash'}), frozenset({'DoubleJump'}), frozenset({'Glide', 'Open', 'ChargeJump'})}, 'HoruL4': {frozenset({'Stomp'})}, 'HoruL4LowerExp': {frozenset({'Grenade', 'Bash', 'Stomp'}), frozenset({'Stomp', 'WallJump'}), frozenset({'Stomp', 'ChargeJump'})}, 'HoruL4ChaseExp': {frozenset({'Free'})}, 'HoruMap': {frozenset({'Mapstone'})}, 'HoruR1EnergyCell': {frozenset({'Climb', 'Glide', 'DoubleJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'Bash', 'Grenade'}), frozenset({'Glide', 'WallJump'})}, 'HoruR3Plant': {frozenset({'Grenade'})}, 'HoruR4DrainedExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Glide', 'DoubleJump'})}, 'HoruR4LaserExp': {frozenset({'Bash', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'InnerSwampDrainExp': {frozenset({'Grenade', 'Bash', 'WallJump', 'Water'}), frozenset({'Climb', 'ChargeJump', 'Water'}), frozenset({'Glide'}), frozenset({'Climb', 'Bash', 'Grenade', 'Water'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeFlame', 'Water', 'Glide', 'Stomp', 'WallJump'}), frozenset({'DoubleJump', 'WallJump', 'Water'}), frozenset({'Grenade', 'Glide', 'Water', 'Bash'}), frozenset({'Glide', 'ChargeJump', 'DoubleJump', 'Water'}), frozenset({'Grenade', 'Bash', 'DoubleJump', 'Water'}), frozenset({'DoubleJump'}), frozenset({'Water', 'Grenade', 'Glide', 'Stomp', 'WallJump'}), frozenset({'Climb', 'DoubleJump', 'Water'}), frozenset({'Climb', 'Dash', 'Glide', 'Water'})}, 'HoruL1': {frozenset({'Grenade', 'Glide', 'Stomp', 'Bash'}), frozenset({'Glide', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Bash', 'Stomp', 'DoubleJump'})}, 'HoruL2': {frozenset({'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Stomp', 'Bash'}), frozenset({'Stomp', 'ChargeJump'})}, 'HoruL3': {frozenset({'Glide', 'Bash', 'Stomp', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb', 'Stomp'}), frozenset({'Stomp', 'DoubleJump', 'Bash'})}, 'WallJumpAreaExp': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'WallJumpAreaEnergyCell': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'LeftGumoHideoutUpperPlant': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Climb', 'ChargeFlame'}), frozenset({'Grenade'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'ChargeFlame', 'DoubleJump'})}, 'FarLeftGumoHideoutExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'DoubleJump'})}, 'LeftSorrowAbilityCell': {frozenset({'Glide', 'Bash'}), frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Glide', 'DoubleJump', 'WallJump'})}, 'LeftSorrowGrenade': {frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Grenade', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash', 'Glide'})}, 'LeftSorrowPlant': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'ChargeFlame', 'DoubleJump', 'WallJump'}), frozenset({'Grenade'})}, 'LeftSorrowKeystone1': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'})}, 'LeftSorrowKeystone2': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'})}, 'LeftSorrowKeystone3': {frozenset({'Glide'})}, 'LeftSorrowKeystone4': {frozenset({'Glide'})}, 'LeftSorrowEnergyCell': {frozenset({'Glide'})}, 'LostGroveLongSwim': {frozenset({'Water'})}, 'LostGroveHiddenExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'LostGroveTeleporter': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'LowerBlackrootAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Grenade', 'Dash', 'Bash'})}, 'LowerBlackrootLaserExp': {frozenset({'Grenade', 'Dash', 'Bash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Dash', 'ChargeJump'}), frozenset({'Climb', 'Dash', 'DoubleJump'})}, 'LowerBlackrootGrenadeThrow': {frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'Climb', 'Grenade'}), frozenset({'Grenade', 'Glide'}), frozenset({'Grenade', 'DoubleJump'})}, 'LowerGinsoHiddenExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'LowerGinsoPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'LeftGumoHideoutLowerPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'GumoHideoutLeftHangingExp': {frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'LeftGumoHideoutExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'LeftGumoHideoutHealthCell': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'ChargeJump'})}, 'LeftGumoHideoutSwim': {frozenset({'Water'})}, 'SorrowSpikeKeystone': {frozenset({'Glide'}), frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'})}, 'SorrowHiddenKeystone': {frozenset({'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'}), frozenset({'Glide'})}, 'SorrowHealthCell': {frozenset({'Glide', 'ChargeJump', 'Bash'})}, 'SorrowLowerLeftKeystone': {frozenset({'Glide'})}, 'SpiritCavernsKeystone2': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'SpiritCavernsAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Bash'})}, 'LowerValleyMapstone': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'KuroPerchExp': {frozenset({'Glide', 'Wind'}), frozenset({'Bash', 'OpenWorld'}), frozenset({'Glide'}), frozenset({'Bash'}), frozenset({'Glide', 'OpenWorld'}), frozenset({'Stomp'})}, 'ValleyMainPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'MistyGrenade': {frozenset({'Grenade'})}, 'MistyEntranceStompExp': {frozenset({'Stomp'})}, 'MistyEntranceTreeExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'MistyPostClimbAboveSpikePit': {frozenset({'Glide', 'Bash', 'WallJump'}), frozenset({'Climb', 'Bash', 'Glide'})}, 'GumonSeal': {frozenset({'Climb'}), frozenset({'DoubleJump'}), frozenset({'Bash'}), frozenset({'WallJump'})}, 'MistyFrogNookExp': {frozenset({'Grenade', 'Bash', 'DoubleJump'}), frozenset({'Glide', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'DoubleJump'})}, 'MistyPostClimbSpikeCave': {frozenset({'Glide', 'Bash', 'DoubleJump'})}, 'MistyAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'MistyMortarCorridorUpperExp': {frozenset({'Glide', 'Bash'})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Glide'})}, 'MistyPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'GrottoEnergyDoorSwim': {frozenset({('EC', 2), 'Water'})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'ChargeJump'}), frozenset({('EC', 2), 'Bash', 'Grenade'}), frozenset({('EC', 2), 'DoubleJump', 'WallJump'})}, 'AboveGrottoTeleporterExp': {frozenset({'Grenade', 'Bash'}), frozenset({'ChargeJump'}), frozenset({'Climb', 'Bash'}), frozenset({'DoubleJump'}), frozenset({'Bash', 'WallJump'})}, 'LeftGrottoTeleporterExp': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'})}, 'BelowGrottoTeleporterHealthCell': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump'})}, 'BelowGrottoTeleporterPlant': {frozenset({'ChargeFlame', 'Glide'}), frozenset({'Grenade', 'Glide'}), frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'Grenade', 'DoubleJump'})}, 'MoonGrottoStompPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'GrottoSwampDrainAccessExp': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Glide', 'Bash', 'DoubleJump'})}, 'GrottoSwampDrainAccessPlant': {frozenset({'Grenade', 'Stomp'}), frozenset({'ChargeFlame', 'Stomp', 'Climb', 'ChargeJump'}), frozenset({'ChargeFlame', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'ChargeFlame', 'Stomp', 'ChargeJump', 'Glide'}), frozenset({'ChargeFlame', 'Stomp', 'ChargeJump', 'DoubleJump'})}, 'OuterSwampStompExp': {frozenset({'Glide', 'Wind'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'OuterSwampHealthCell': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'OuterSwampMortarPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'OuterSwampGrenadeExp': {frozenset({'Grenade', 'ChargeJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Grenade', 'Climb'})}, 'OutsideForlornTreeExp': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'OutsideForlornWaterExp': {frozenset({'Water'})}, 'OutsideForlornCliffExp': {frozenset({'Glide'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Dash'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'HoruR1HangingExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Glide', 'DoubleJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'})}, 'HoruR2': {frozenset({'ChargeJump', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'Grenade', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump', 'Bash'})}, 'RightForlornPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'StompAreaExp': {frozenset({'Bash'}), frozenset({'Stomp'})}, 'StompAreaRoofExp': {frozenset({'ChargeJump'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', 'Glide', 'Water'}), frozenset({'Climb', 'Water', 'Grenade', 'Glide', 'ChargeJump'}), frozenset({'Grenade', 'Stomp', 'ChargeJump', 'Water'}), frozenset({'Grenade', 'Bash', 'Stomp', 'Water'})}, 'SorrowMapstone': {frozenset({'Bash'})}, 'SorrowMap': {frozenset({'Bash', 'Mapstone'}), frozenset({'Stomp', 'Mapstone'})}, 'SpiderSacHealthCell': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump'}), frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'ChargeFlame', 'Climb', 'ChargeJump'}), frozenset({'Grenade', 'DoubleJump'})}, 'SpiderSacEnergyDoor': {frozenset({('EC', 4)})}, 'SpiderSacGrenadeDoor': {frozenset({'Grenade', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'GroveSpiderWaterSwim': {frozenset({'Water'})}, 'GroveAboveSpiderWaterExp': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Grenade', 'Bash'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'})}, 'GroveAboveSpiderWaterEnergyCell': {frozenset({'Grenade', 'Climb', 'ChargeJump', 'DoubleJump'})}, 'AboveChargeFlameTreeExp': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'})}, 'GladesGrenadePool': {frozenset({'Grenade', 'Water'})}, 'GladesGrenadeTree': {frozenset({'Grenade', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'GladesMainPool': {frozenset({'Water'})}, 'GladesMainPoolDeep': {frozenset({'Water'})}, 'FronkeyWalkRoof': {frozenset({'ChargeJump'}), frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash'})}, 'SunstonePlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'SwampMap': {frozenset({'Mapstone'})}, 'SwampEntranceSwim': {frozenset({'Water'})}, 'SwampEntrancePlant': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'ChargeFlame', 'Climb'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Grenade', 'Climb'})}, 'InnerSwampStompExp': {frozenset({'Stomp', 'Water'})}, 'InnerSwampSwimRightKeystone': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'Bash'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Glide', 'WallJump'})}, 'TopGinsoLeftLowerExp': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'})}, 'TopGinsoLeftUpperExp': {frozenset({'ChargeJump'}), frozenset({'Bash'})}, 'TopGinsoRightPlant': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'UpperGinsoRedirectLowerExp': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Stomp', 'GinsoKey'})}, 'UpperGinsoRedirectUpperExp': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Stomp', 'GinsoKey'})}, 'UpperGinsoLowerKeystone': {frozenset({'Glide', 'Bash', 'GinsoKey'}), frozenset({'Bash', 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoRightKeystone': {frozenset({'Glide', 'Bash', 'GinsoKey'}), frozenset({'Bash', 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoUpperRightKeystone': {frozenset({'Bash', 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoUpperLeftKeystone': {frozenset({'Bash', 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoEnergyCell': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Stomp', 'GinsoKey'})}, 'GrottoLasersRoofExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'LeftGladesExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'UpperSorrowRightKeystone': {frozenset({'Glide'})}, 'UpperSorrowFarRightKeystone': {frozenset({'Glide'})}, 'UpperSorrowLeftKeystone': {frozenset({'Glide'})}, 'UpperSorrowSpikeExp': {frozenset({'Glide'})}, 'UpperSorrowFarLeftKeystone': {frozenset({'Glide'})}, 'SpiritCavernsTopLeftKeystone': {frozenset({'Climb', 'DoubleJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'Glide'})}, 'ValleyThreeBirdAbilityCell': {frozenset({'Glide', 'Wind'}), frozenset({'Glide', 'OpenWorld', 'Wind'}), frozenset({'Bash', 'OpenWorld'}), frozenset({'ChargeJump', 'OpenWorld'}), frozenset({'Bash'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Climb', 'Glide', 'ChargeJump'})}, 'ValleyEntryGrenadeLongSwim': {frozenset({'Grenade', 'Water'})}, 'ValleyEntryTreePlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'ValleyForlornApproachGrenade': {frozenset({'Grenade'})}, 'ValleyMap': {frozenset({'Bash', 'Mapstone'})}, 'ValleyRightSwimExp': {frozenset({'Water'})}, 'ValleyRightBirdStompCell': {frozenset({'Climb', 'ChargeJump'})}, 'ValleyRightFastStomplessCell': {frozenset({'Glide', 'Wind'})}, 'ValleyRightExp': {frozenset({'Bash'})}, 'ValleyMainFACS': {frozenset({'Climb', 'ChargeJump'})}, 'WilhelmExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash', 'Climb'})}}, 'dbash': {'AboveChargeJumpAbilityCell': {frozenset({'Bash'})}, 'GrenadeSkillTree': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Bash', 'DoubleJump'})}, 'GrenadeAreaExp': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Bash', 'DoubleJump'})}, 'HollowGroveTreeAbilityCell': {frozenset({'Bash'})}, 'HoruFieldsEnergyCell': {frozenset({'Bash'})}, 'HoruLavaDrainedRightExp': {frozenset({'Open', 'Bash'}), frozenset({'Bash'})}, 'HoruR4DrainedExp': {frozenset({'Bash'})}, 'HoruR4LaserExp': {frozenset({'Bash'})}, 'LeftSorrowGrenade': {frozenset({'Grenade', 'Bash'})}, 'GumoHideoutLeftHangingExp': {frozenset({'Bash'})}, 'GumoHideoutRightHangingExp': {frozenset({'Bash'})}, 'LeftGumoHideoutExp': {frozenset({'Bash'})}, 'LeftGumoHideoutHealthCell': {frozenset({'Bash'})}, 'SorrowSpikeKeystone': {frozenset({'Bash'})}, 'SorrowHiddenKeystone': {frozenset({'Bash'})}, 'SorrowHealthCell': {frozenset({'Bash'})}, 'AboveGrottoTeleporterExp': {frozenset({'Bash'})}, 'GrottoSwampDrainAccessExp': {frozenset({'Bash'})}, 'StompAreaRoofExp': {frozenset({'Bash'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', 'Water'})}, 'GroveAboveSpiderWaterExp': {frozenset({'Bash'})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Bash'})}, 'ValleyMainFACS': {frozenset({'Bash'})}, 'WilhelmExp': {frozenset({'Bash'})}}, 'expert-abilities': {'AboveChargeJumpAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'BashAreaExp': {frozenset({('AC', 6), 'Dash', 'GinsoKey'}), frozenset({('AC', 6), 'Dash', 'GinsoKey', 'DoubleJump', 'WallJump'})}, 'ChargeFlameAreaPlant': {frozenset({'Dash', ('AC', 6)})}, 'DashAreaPlant': {frozenset({'Dash', ('AC', 6)})}, 'DeathGauntletRoofPlant': {frozenset({'Dash', ('AC', 6)})}, 'DoubleJumpAreaExp': {frozenset({'Dash', ('AC', 6), ('EC', 1)})}, 'ForlornHiddenSpiderExp': {frozenset({'ForlornKey', ('AC', 6), 'Dash'})}, 'ForlornPlant': {frozenset({'Dash', ('AC', 6)})}, 'ForlornKeystone3': {frozenset({'ForlornKey', ('AC', 6), 'Dash', 'WallJump'}), frozenset({'Climb', 'ForlornKey', ('AC', 6), 'Dash'})}, 'GladesLaser': {frozenset({'Dash', ('AC', 6)})}, 'GladesLaserGrenade': {frozenset({('AC', 6), ('EC', 1), 'Dash', 'Grenade', 'DoubleJump', 'WallJump'}), frozenset({('AC', 6), ('EC', 1), 'Climb', 'Dash', 'Grenade', 'Glide', 'ChargeJump'}), frozenset({('AC', 6), ('EC', 2), 'Climb', 'Dash', 'Grenade', 'ChargeJump'})}, 'GrenadeSkillTree': {frozenset({'Dash', ('AC', 6)})}, 'GrenadeAreaExp': {frozenset({'Dash', ('AC', 6)})}, 'GrenadeAreaAbilityCell': {frozenset({'Grenade', 'Dash', ('AC', 6)})}, 'GumoHideoutRedirectPlant': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}, 'HollowGroveTreePlant': {frozenset({'Dash', ('AC', 6)})}, 'HollowGroveTreeAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'HollowGroveMapPlant': {frozenset({'Dash', ('AC', 6)})}, 'SwampTeleporterAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'HoruFieldsPlant': {frozenset({'Dash', ('AC', 6), ('EC', 3)})}, 'HoruFieldsEnergyCell': {frozenset({('EC', 2), 'Dash', ('AC', 6)})}, 'HoruFieldsHiddenExp': {frozenset({'Dash', ('AC', 6)})}, 'HoruLavaDrainedLeftExp': {frozenset({'Open', ('AC', 6), 'Dash'})}, 'HoruLavaDrainedRightExp': {frozenset({'Open', ('AC', 6), 'Dash'})}, 'HoruL4LowerExp': {frozenset({('EC', 2), 'Dash', ('AC', 6)}), frozenset({'Dash', 'Stomp', ('AC', 3)})}, 'HoruR3Plant': {frozenset({'Dash', ('AC', 6)})}, 'HoruR4DrainedExp': {frozenset({'Dash', ('AC', 6), ('EC', 1)}), frozenset({'Dash', ('AC', 6)})}, 'HoruR4LaserExp': {frozenset({('AC', 6), 'Dash', 'ChargeJump', ('EC', 2)})}, 'HoruL1': {frozenset({'Dash', 'Stomp', ('AC', 3), 'Bash'}), frozenset({('AC', 6), 'Dash', ('EC', 2), 'Stomp', 'DoubleJump'}), frozenset({('AC', 6), 'Dash', 'Stomp', ('EC', 3)})}, 'HoruL2': {frozenset({'Stomp', ('AC', 6), 'Dash', ('EC', 1)}), frozenset({'Climb', 'Stomp', 'Dash', ('AC', 3)})}, 'HoruL3': {frozenset({('AC', 6), 'Climb', 'Dash', ('EC', 2), 'ChargeJump'})}, 'LeftGumoHideoutUpperPlant': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}, 'LeftSorrowPlant': {frozenset({'Dash', ('AC', 6)})}, 'LowerBlackrootAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'LowerBlackrootLaserExp': {frozenset({'Dash', ('AC', 6)})}, 'LowerGinsoPlant': {frozenset({'Dash', ('AC', 6)})}, 'LeftGumoHideoutLowerPlant': {frozenset({'Dash', ('AC', 6)})}, 'LeftGumoHideoutHealthCell': {frozenset({'Dash', ('AC', 6)})}, 'SorrowSpikeKeystone': {frozenset({'Dash', ('AC', 6)})}, 'SorrowHiddenKeystone': {frozenset({'Dash', ('AC', 6)})}, 'SorrowLowerLeftKeystone': {frozenset({'Dash', ('AC', 6), 'Bash'}), frozenset({('EC', 2), 'Dash', ('AC', 6)}), frozenset({'Dash', ('AC', 6), 'DoubleJump'}), frozenset({('AC', 6), 'Dash', 'Stomp'})}, 'SpiritCavernsKeystone2': {frozenset({'Dash', ('AC', 6)})}, 'SpiritCavernsAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'LowerValleyMapstone': {frozenset({'Dash', ('AC', 6)})}, 'KuroPerchExp': {frozenset({'Dash', ('AC', 6), 'OpenWorld'}), frozenset({'Dash', ('AC', 3), 'ChargeJump', 'WallJump'}), frozenset({'Dash', ('AC', 6)})}, 'ValleyMainPlant': {frozenset({'Dash', ('AC', 6)})}, 'MistyEntranceTreeExp': {frozenset({'Dash', ('AC', 6)})}, 'MistyFrogNookExp': {frozenset({'Dash', ('AC', 6)})}, 'MistyMortarCorridorUpperExp': {frozenset({'Dash', ('AC', 6)})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Dash', ('AC', 6), 'DoubleJump'})}, 'MistyPlant': {frozenset({'Dash', ('AC', 6)})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'Dash', ('AC', 6)})}, 'AboveGrottoTeleporterExp': {frozenset({'Dash', ('AC', 6)})}, 'BelowGrottoTeleporterHealthCell': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}, 'BelowGrottoTeleporterPlant': {frozenset({'Dash', ('AC', 6)})}, 'MoonGrottoStompPlant': {frozenset({'Dash', ('AC', 6)})}, 'GrottoSwampDrainAccessExp': {frozenset({'Dash', ('AC', 6)})}, 'GrottoSwampDrainAccessPlant': {frozenset({'Dash', ('AC', 6)})}, 'OuterSwampStompExp': {frozenset({'Dash', ('AC', 6)})}, 'OuterSwampHealthCell': {frozenset({'Dash', ('AC', 6)})}, 'OuterSwampMortarPlant': {frozenset({'Dash', ('AC', 6)})}, 'RightForlornPlant': {frozenset({'Dash', ('AC', 6)})}, 'StompAreaExp': {frozenset({'Dash', ('AC', 6), ('EC', 1)})}, 'StompAreaGrenadeExp': {frozenset({('AC', 6), 'Dash', 'Water', 'Grenade', 'Stomp'}), frozenset({('AC', 6), 'Dash', ('EC', 3), 'Water', 'Grenade'})}, 'SorrowMapstone': {frozenset({'Dash', ('AC', 6)})}, 'AboveChargeFlameTreeExp': {frozenset({'Dash', ('AC', 6)})}, 'SpiderSacHealthCell': {frozenset({'Dash', ('AC', 6)})}, 'SpiderSacGrenadeDoor': {frozenset({'Grenade', 'Dash', ('AC', 6)})}, 'GroveAboveSpiderWaterExp': {frozenset({'Dash', ('AC', 6)})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Dash', ('AC', 6)})}, 'GroveAboveSpiderWaterEnergyCell': {frozenset({'Grenade', 'Dash', ('AC', 6)})}, 'GladesGrenadeTree': {frozenset({'Grenade', 'Dash', ('AC', 6)})}, 'FronkeyWalkRoof': {frozenset({'Dash', ('AC', 6)})}, 'SunstonePlant': {frozenset({'Dash', ('AC', 6)})}, 'InnerSwampDrainExp': {frozenset({'Climb', 'Dash', 'Water', 'Grenade', 'Stomp', ('AC', 3)}), frozenset({'Climb', 'Dash', ('AC', 6), 'Water'}), frozenset({'ChargeFlame', 'Climb', 'Dash', 'Water', 'Stomp', ('AC', 3)}), frozenset({'Dash', ('AC', 3), 'WallJump', 'Water'})}, 'SwampEntrancePlant': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}, 'InnerSwampStompExp': {frozenset({'Dash', 'ChargeJump', ('AC', 3), 'Water'})}, 'TopGinsoLeftLowerExp': {frozenset({'Dash', ('AC', 6)})}, 'TopGinsoLeftUpperExp': {frozenset({'Dash', ('AC', 6)})}, 'TopGinsoRightPlant': {frozenset({'Dash', ('AC', 6)})}, 'UpperGinsoRedirectLowerExp': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoRedirectUpperExp': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoLowerKeystone': {frozenset({('AC', 6), 'Dash', 'GinsoKey'})}, 'GrottoLasersRoofExp': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)})}, 'UpperSorrowLeftKeystone': {frozenset({('EC', 2), 'Dash', ('AC', 6)})}, 'ValleyThreeBirdAbilityCell': {frozenset({'Dash', ('AC', 6)}), frozenset({'Dash', ('AC', 6), 'OpenWorld'})}, 'ValleyEntryTreePlant': {frozenset({'Dash', ('AC', 6)})}, 'ValleyMap': {frozenset({'Grenade', 'Dash', 'Mapstone', ('AC', 3)}), frozenset({'ChargeFlame', 'Dash', 'Mapstone', ('AC', 3)})}, 'ValleyMainFACS': {frozenset({'WallJump', 'Dash', 'ChargeJump', 'DoubleJump', ('AC', 3)}), frozenset({'Wind', 'Dash', 'Glide', ('AC', 3), 'ChargeJump', 'WallJump'})}}, 'master-abilities': {'BashAreaExp': {frozenset({('AC', 12), 'GinsoKey', 'DoubleJump'})}, 'ForlornHiddenSpiderExp': {frozenset({'ForlornKey', ('AC', 12), 'DoubleJump'})}, 'ForlornKeystone2': {frozenset({'ForlornKey', ('AC', 12), 'DoubleJump'})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', ('AC', 12), 'DoubleJump'})}, 'GumoHideoutRedirectPlant': {frozenset({'Dash', ('AC', 6), 'DoubleJump'})}, 'SwampTeleporterAbilityCell': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump'})}, 'HoruFieldsAbilityCell': {frozenset({'Glide', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'HoruLavaDrainedLeftExp': {frozenset({'Open', ('AC', 12), 'DoubleJump'})}, 'HoruLavaDrainedRightExp': {frozenset({'Open', 'ChargeJump', 'DoubleJump', ('AC', 12)}), frozenset({'Glide', 'Open', ('AC', 12), 'DoubleJump'})}, 'HoruR4DrainedExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'HoruL1': {frozenset({('AC', 6), ('EC', 1), 'Dash', 'Stomp', 'DoubleJump'})}, 'HoruL2': {frozenset({'Stomp', 'DoubleJump', ('AC', 3), 'Dash'}), frozenset({'Stomp', ('AC', 12), 'DoubleJump'})}, 'HoruL3': {frozenset({('AC', 6), 'Dash', ('EC', 6), 'DoubleJump', 'WallJump'}), frozenset({('AC', 6), 'Dash', ('EC', 2), 'Stomp', 'DoubleJump'}), frozenset({('AC', 6), 'Dash', 'Stomp', ('EC', 3)}), frozenset({('AC', 6), ('EC', 4), 'Dash', 'Glide', 'DoubleJump'}), frozenset({'Dash', ('AC', 6), ('EC', 7)}), frozenset({'Glide', 'Dash', ('AC', 6), ('EC', 6)}), frozenset({('AC', 12), 'Climb', 'Dash', 'Glide', 'ChargeJump', 'DoubleJump'}), frozenset({'Bash', ('AC', 6), 'Dash', ('EC', 1)}), frozenset({('AC', 6), 'Climb', 'Dash', ('EC', 6), 'DoubleJump'})}, 'LeftSorrowAbilityCell': {frozenset({'Climb', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'LowerGinsoHiddenExp': {frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({'Dash', ('AC', 6), 'WallJump'})}, 'LeftGumoHideoutExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'LeftGumoHideoutHealthCell': {frozenset({('AC', 12), 'DoubleJump'})}, 'SorrowSpikeKeystone': {frozenset({'Climb', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'SorrowLowerLeftKeystone': {frozenset({('AC', 12), 'DoubleJump'})}, 'SpiritCavernsAbilityCell': {frozenset({('AC', 12), 'DoubleJump'})}, 'MistyFrogNookExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'MistyMortarCorridorUpperExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'MistyMortarCorridorHiddenExp': {frozenset({('AC', 12), 'DoubleJump'}), frozenset({'Dash', ('AC', 6)})}, 'BelowGrottoTeleporterHealthCell': {frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'OuterSwampHealthCell': {frozenset({('AC', 12), 'DoubleJump'})}, 'SpiderSacHealthCell': {frozenset({'Dash', ('AC', 6), 'DoubleJump'})}, 'TopGinsoLeftUpperExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'TopGinsoRightPlant': {frozenset({'ChargeFlame', ('AC', 12), 'DoubleJump'}), frozenset({'Grenade', ('AC', 12), 'DoubleJump'})}, 'UpperSorrowRightKeystone': {frozenset({('AC', 6), 'Dash', 'Grenade', 'Bash', 'DoubleJump'})}, 'UpperSorrowFarRightKeystone': {frozenset({('AC', 12), 'Dash', 'Grenade', 'Bash', 'DoubleJump'})}, 'ValleyThreeBirdAbilityCell': {frozenset({('AC', 12), 'DoubleJump'})}, 'WilhelmExp': {frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'KuroPerchExp': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'master-core': {'DashAreaRoofExp': {frozenset({'DoubleJump'}), frozenset({'Bash'})}, 'DoubleJumpAreaExp': {frozenset({'DoubleJump'})}, 'ForlornKeystone4': {frozenset({'Grenade', 'ForlornKey', 'DoubleJump', 'Bash'}), frozenset({'ForlornKey', 'ChargeJump', 'DoubleJump'})}, 'LowerGinsoKeystone3': {frozenset({'DoubleJump'})}, 'LowerGinsoKeystone4': {frozenset({'DoubleJump'})}, 'GladesLaserGrenade': {frozenset({'Grenade', 'Bash', 'DoubleJump'})}, 'GrenadeSkillTree': {frozenset({'ChargeJump'})}, 'GrenadeAreaAbilityCell': {frozenset({'Grenade', 'ChargeJump'})}, 'GumoHideoutMiniboss': {frozenset({'DoubleJump'})}, 'GumoHideoutEnergyCell': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'}), frozenset({'DoubleJump'})}, 'HollowGroveTreeAbilityCell': {frozenset({'Stomp', 'DoubleJump'})}, 'SwampTeleporterAbilityCell': {frozenset({'Glide', 'ChargeJump', 'DoubleJump'})}, 'DoorWarpExp': {frozenset({'DoubleJump'})}, 'HoruFieldsPlant': {frozenset({'Grenade', 'Glide'}), frozenset({'Grenade', 'Dash'}), frozenset({'Grenade', 'DoubleJump'})}, 'HoruFieldsAbilityCell': {frozenset({'Bash'})}, 'HoruL4LowerExp': {frozenset({'Dash', 'Stomp'})}, 'HoruR1EnergyCell': {frozenset({'DoubleJump'})}, 'HoruL2': {frozenset({'Glide', 'Stomp', 'DoubleJump'})}, 'HoruL3': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'Bash', 'Stomp'})}, 'WallJumpAreaEnergyCell': {frozenset({'DoubleJump'})}, 'FarLeftGumoHideoutExp': {frozenset({'Bash'})}, 'LeftSorrowAbilityCell': {frozenset({'Bash'})}, 'LeftSorrowKeystone2': {frozenset({'Bash'})}, 'LeftSorrowKeystone3': {frozenset({'Bash'})}, 'LeftSorrowKeystone4': {frozenset({'Bash'})}, 'LeftSorrowEnergyCell': {frozenset({'Bash'})}, 'LowerBlackrootAbilityCell': {frozenset({'DoubleJump'})}, 'LowerGinsoHiddenExp': {frozenset({'DoubleJump'})}, 'SorrowSpikeKeystone': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump'})}, 'SorrowLowerLeftKeystone': {frozenset({'Bash'})}, 'SpiritCavernsKeystone2': {frozenset({'Free'})}, 'LowerValleyMapstone': {frozenset({'Free'})}, 'MistyEntranceStompExp': {frozenset({('EC', 2), 'Dash', ('AC', 6)}), frozenset({'ChargeFlame', 'Dash'})}, 'MistyEntranceTreeExp': {frozenset({'DoubleJump'}), frozenset({'WallJump'})}, 'MistyPostClimbAboveSpikePit': {frozenset({'Bash'})}, 'MistyMortarCorridorUpperExp': {frozenset({'Bash'})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Bash'})}, 'OuterSwampHealthCell': {frozenset({'Glide', 'DoubleJump'}), frozenset({'Bash'})}, 'OutsideForlornTreeExp': {frozenset({'Bash'})}, 'HoruR1HangingExp': {frozenset({'Glide', 'WallJump'})}, 'HoruR2': {frozenset({'Stomp', 'DoubleJump'})}, 'HoruR4DrainedExp': {frozenset({'Bash'})}, 'StompAreaExp': {frozenset({'Grenade'})}, 'AboveChargeFlameTreeExp': {frozenset({'Glide', 'Bash', 'DoubleJump'}), frozenset({'Stomp', 'DoubleJump'}), frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'Grenade', 'DoubleJump'})}, 'SpiderSacHealthCell': {frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'Grenade', 'DoubleJump'})}, 'SpiderSacEnergyDoor': {frozenset({('EC', 2)})}, 'InnerSwampDrainExp': {frozenset({'DoubleJump', 'Water'})}, 'TopGinsoLeftLowerExp': {frozenset({'DoubleJump'})}, 'UpperGinsoRedirectLowerExp': {frozenset({'Grenade', 'GinsoKey'})}, 'GrottoLasersRoofExp': {frozenset({'Glide', 'DoubleJump'}), frozenset({'Bash'})}, 'SpiritCavernsTopLeftKeystone': {frozenset({'DoubleJump'}), frozenset({'Climb'})}, 'KuroPerchExp': {frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Bash'}), frozenset({'Glide', 'ChargeJump'})}}, 'glitched': {'BlackrootBoulderExp': {frozenset({'Free'})}, 'GroveWaterStompAbilityCell': {frozenset({'Bash'})}, 'SpiderSacEnergyDoor': {frozenset({('EC', 3)})}, 'GladesGrenadeTree': {frozenset({'Grenade'})}, 'KuroPerchExp': {frozenset({'ChargeJump'})}}, 'standard-abilities': {'BlackrootMap': {frozenset({'Climb', 'Dash', 'Mapstone', ('AC', 3)})}, 'DoubleJumpSkillTree': {frozenset({'Dash', ('AC', 3)})}, 'DoubleJumpAreaExp': {frozenset({'Dash', 'ChargeJump', ('AC', 3)}), frozenset({'Bash', 'Dash', ('AC', 3)})}, 'ForlornKeystone3': {frozenset({'ForlornKey', 'ChargeJump', 'Dash', ('AC', 3)})}, 'LowerGinsoKeystone1': {frozenset({'Dash', ('AC', 3)})}, 'LowerGinsoKeystone2': {frozenset({'Dash', ('AC', 3)})}, 'GladesLaserGrenade': {frozenset({'Dash', 'Grenade', 'Glide', ('AC', 3), 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Dash', 'Grenade', 'ChargeJump', 'DoubleJump', ('AC', 3)})}, 'GumoHideoutMapstone': {frozenset({'Dash', ('AC', 3)})}, 'GumoHideoutRedirectAbilityCell': {frozenset({'Dash', ('AC', 3)})}, 'HollowGroveTreeAbilityCell': {frozenset({'WallJump', 'Dash', 'Glide', 'Stomp', ('AC', 3)}), frozenset({'Climb', 'Dash', 'Glide', 'Stomp', ('AC', 3)})}, 'SwampTeleporterAbilityCell': {frozenset({'Dash', 'Glide', 'ChargeJump', 'DoubleJump', ('AC', 3)})}, 'HoruFieldsPlant': {frozenset({'Dash', 'Grenade', 'ChargeJump', 'DoubleJump', ('AC', 3)}), frozenset({'ChargeFlame', 'Dash', 'ChargeJump', 'DoubleJump', ('AC', 3)})}, 'HoruFieldsEnergyCell': {frozenset({'Dash', 'ChargeJump', 'DoubleJump', ('AC', 3)}), frozenset({'Glide', 'ChargeJump', 'Dash', ('AC', 3)})}, 'HoruLavaDrainedLeftExp': {frozenset({'Glide', 'Open', 'Dash', ('AC', 3)})}, 'HoruR1EnergyCell': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}, 'HoruR4DrainedExp': {frozenset({'Dash', 'DoubleJump', ('AC', 3)}), frozenset({'Glide', 'Dash', ('AC', 3)})}, 'InnerSwampDrainExp': {frozenset({'Dash', ('AC', 3)})}, 'HoruL1': {frozenset({'WallJump', 'Dash', 'Stomp', ('AC', 3), 'Bash'}), frozenset({'Dash', 'Grenade', 'Stomp', ('AC', 3), 'Bash'}), frozenset({'Dash', 'Stomp', 'ChargeJump', ('AC', 3), 'Bash'}), frozenset({'Climb', 'Dash', 'Stomp', ('AC', 3), 'Bash'})}, 'HoruL2': {frozenset({'Stomp', ('AC', 3), 'Dash', 'WallJump'}), frozenset({'Climb', 'Dash', 'Stomp', 'DoubleJump', ('AC', 3)})}, 'HoruL3': {frozenset({'Bash', 'Stomp', 'Dash', ('AC', 3)}), frozenset({'ChargeFlame', 'Bash', 'Dash', ('AC', 3)})}, 'FarLeftGumoHideoutExp': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}, 'GumoHideoutLeftHangingExp': {frozenset({'Dash', ('AC', 3)})}, 'MistyFrogNookExp': {frozenset({'Dash', ('AC', 3), 'DoubleJump', 'WallJump'})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'Climb', 'Dash', ('AC', 3)})}, 'BelowGrottoTeleporterPlant': {frozenset({'Grenade', 'Dash', ('AC', 3)}), frozenset({'ChargeFlame', 'Dash', ('AC', 3)})}, 'GrottoSwampDrainAccessPlant': {frozenset({'ChargeFlame', 'Dash', ('AC', 3), 'WallJump'}), frozenset({'ChargeFlame', 'Glide', 'Dash', ('AC', 3)})}, 'HoruR1HangingExp': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}, 'HoruLavaDrainedRightExp': {frozenset({'Dash', ('AC', 3)})}, 'AboveChargeFlameTreeExp': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}, 'UpperGinsoLowerKeystone': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoRightKeystone': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoUpperLeftKeystone': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}}, 'expert-core': {'BlackrootMap': {frozenset({'Climb', 'Mapstone'})}, 'DashAreaMapstone': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DoubleJumpSkillTree': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'})}, 'DoubleJumpAreaExp': {frozenset({'Climb', 'Bash', 'Water'}), frozenset({'Grenade', 'Bash'})}, 'ForlornHiddenSpiderExp': {frozenset({'ForlornKey', 'DoubleJump', 'WallJump'})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', 'Open'})}, 'GladesLaserGrenade': {frozenset({'Water', 'Grenade', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump', 'Water'})}, 'GrenadeSkillTree': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Dash', 'Bash'})}, 'GumoHideoutCrusherExp': {frozenset({'DoubleJump'})}, 'GumoHideoutCrusherKeystone': {frozenset({'DoubleJump'})}, 'SwampTeleporterAbilityCell': {frozenset({'Grenade', 'Bash'})}, 'HoruL4LowerExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'})}, 'HoruR1EnergyCell': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Climb', 'Glide'})}, 'HoruR4DrainedExp': {frozenset({'Glide', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'HoruL1': {frozenset({'Glide', 'Stomp', 'Bash'})}, 'HoruL2': {frozenset({'Climb', 'Stomp', 'Glide', 'DoubleJump'})}, 'HoruL3': {frozenset({'Grenade', 'Bash', 'ChargeJump'})}, 'LeftGumoHideoutUpperPlant': {frozenset({'ChargeFlame'})}, 'LeftSorrowKeystone1': {frozenset({'ChargeJump', 'WallJump'})}, 'LeftSorrowKeystone2': {frozenset({'ChargeJump', 'WallJump'})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Glide', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'LowerBlackrootLaserExp': {frozenset({'Grenade', 'Bash'}), frozenset({'DoubleJump'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'GumoHideoutRightHangingExp': {frozenset({'DoubleJump'})}, 'LeftGumoHideoutExp': {frozenset({'Climb', 'DoubleJump'})}, 'SorrowHiddenKeystone': {frozenset({'Bash', 'ChargeJump', 'WallJump'})}, 'SorrowHealthCell': {frozenset({'Climb', 'ChargeJump'})}, 'SorrowLowerLeftKeystone': {frozenset({'Bash', 'DoubleJump'})}, 'SpiritCavernsAbilityCell': {frozenset({'Climb', 'DoubleJump'})}, 'KuroPerchExp': {frozenset({'Glide', 'ChargeJump', 'WallJump'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'})}, 'MistyEntranceStompExp': {frozenset({'Climb', 'Dash', 'ChargeJump'})}, 'MistyEntranceTreeExp': {frozenset({'Bash'})}, 'MistyPostClimbAboveSpikePit': {frozenset({'Bash', 'DoubleJump'})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Bash', 'DoubleJump'})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'Climb', 'Glide'})}, 'LeftGrottoTeleporterExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'HoruR1HangingExp': {frozenset({'DoubleJump'}), frozenset({'Dash'})}, 'HoruR2': {frozenset({'Stomp', 'WallJump'}), frozenset({'Grenade', 'Stomp', 'Bash'}), frozenset({'Climb', 'Stomp'}), frozenset({'Stomp', 'ChargeJump'})}, 'StompAreaExp': {frozenset({'ChargeFlame'})}, 'AboveChargeFlameTreeExp': {frozenset({'ChargeFlame', 'Climb', 'Glide'}), frozenset({'Dash', 'WallJump'}), frozenset({'Grenade', 'Climb', 'Glide'}), frozenset({'ChargeFlame', 'Glide', 'WallJump'}), frozenset({'Grenade', 'Glide', 'WallJump'}), frozenset({'Climb', 'Stomp', 'Glide'}), frozenset({'Glide', 'Stomp', 'WallJump'}), frozenset({'Climb', 'Dash'})}, 'SpiderSacGrenadeDoor': {frozenset({'Grenade', 'Climb', 'DoubleJump'})}, 'InnerSwampDrainExp': {frozenset({'ChargeJump', 'DoubleJump', 'Water'}), frozenset({'Glide', 'Dash', 'WallJump', 'Water'})}, 'SwampEntrancePlant': {frozenset({'Grenade'})}, 'InnerSwampStompExp': {frozenset({'Grenade', 'Bash', 'ChargeJump', 'Water'})}, 'InnerSwampSwimRightKeystone': {frozenset({'DoubleJump'})}, 'UpperGinsoRedirectLowerExp': {frozenset({'ChargeFlame', 'GinsoKey'})}, 'UpperGinsoRedirectUpperExp': {frozenset({'Climb', 'GinsoKey', 'ChargeJump'}), frozenset({'ChargeFlame', 'GinsoKey'})}, 'UpperGinsoEnergyCell': {frozenset({'Dash', 'GinsoKey', 'ChargeJump'}), frozenset({'ChargeFlame', 'GinsoKey'})}, 'LeftGladesExp': {frozenset({'DoubleJump'}), frozenset({'Bash'})}, 'UpperSorrowLeftKeystone': {frozenset({'Grenade', 'Bash'})}, 'ValleyMap': {frozenset({'Grenade', 'Mapstone', 'DoubleJump'}), frozenset({'Grenade', 'Mapstone', 'ChargeJump'}), frozenset({'ChargeFlame', 'Mapstone', 'ChargeJump'}), frozenset({'ChargeFlame', 'Mapstone', 'DoubleJump'})}, 'WilhelmExp': {frozenset({'Climb', 'Bash'}), frozenset({'Grenade', 'Bash'})}}, 'expert-dboost': {'UpperSorrowSpikeExp': {frozenset({('AC', 6), 'Dash', 'ChargeJump', ('HC', 2)}), frozenset({('EC', 2), 'Dash', ('AC', 6), ('HC', 2)}), frozenset({'Grenade', 'Bash', 'DoubleJump', ('HC', 2)}), frozenset({('AC', 6), 'Dash', ('HC', 2), 'Grenade', 'Bash'})}, 'DeathGauntletStompSwim': {frozenset({('HC', 0)})}, 'DoubleJumpAreaExp': {frozenset({'Climb', 'Bash', ('HC', -1)})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', 'WallJump', ('HC', 1)})}, 'GladesLaser': {frozenset({'Glide', 'WallJump'})}, 'GladesLaserGrenade': {frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Climb', 'Dash', 'Grenade', 'Glide'}), frozenset({'Grenade', 'Glide', 'ChargeJump', ('HC', 0)}), frozenset({('AC', 6), ('EC', 1), 'Climb', 'Dash', ('HC', 2), 'Grenade'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Climb', 'Dash', 'Grenade', 'DoubleJump'}), frozenset({('HC', 0), 'Grenade', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Grenade', 'ChargeJump'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Climb', 'Dash', 'Water', 'Grenade'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Dash', 'Grenade', 'Glide', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump', ('HC', 0)}), frozenset({'Grenade', 'ChargeJump', ('HC', 2)}), frozenset({('HC', 0), ('EC', 2), 'Grenade', 'ChargeJump', ('AC', 3)}), frozenset({('AC', 6), ('HC', 0), ('EC', 2), 'Dash', 'Grenade', 'WallJump'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Dash', 'Water', 'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash', 'ChargeJump', ('HC', 0)}), frozenset({'Grenade', 'ChargeJump', ('HC', 0), 'Water'}), frozenset({('AC', 6), ('HC', 0), ('EC', 2), 'Climb', 'Dash', 'Grenade'}), frozenset({('EC', 1), ('HC', 1), 'Grenade', 'ChargeJump', ('AC', 3)}), frozenset({('AC', 6), ('EC', 1), 'Dash', ('HC', 2), 'Grenade', 'WallJump'})}, 'GroveWaterStompAbilityCell': {frozenset({'Stomp', ('HC', 2)}), frozenset({('HC', 3), 'Bash'})}, 'HoruFieldsAbilityCell': {frozenset({'Bash', 'WallJump', ('HC', 2)})}, 'HoruR1EnergyCell': {frozenset({'WallJump', ('HC', 2)}), frozenset({'Climb', ('HC', 2)})}, 'HoruR4DrainedExp': {frozenset({('HC', 3), 'DoubleJump'}), frozenset({('HC', 3), 'Dash', ('AC', 3)}), frozenset({('HC', 3), 'Glide'})}, 'LeftSorrowAbilityCell': {frozenset({'Climb', 'ChargeJump', ('HC', 2)}), frozenset({'ChargeJump', 'WallJump', ('HC', 2)})}, 'LeftSorrowKeystone3': {frozenset({'Climb', 'ChargeJump', ('HC', 2)})}, 'LeftSorrowKeystone4': {frozenset({'Climb', 'ChargeJump', 'DoubleJump', ('HC', 2)}), frozenset({'Climb', 'Dash', 'ChargeJump', ('HC', 2)})}, 'LeftSorrowEnergyCell': {frozenset({'Climb', 'ChargeJump', 'DoubleJump', ('HC', 2)})}, 'LowerBlackrootAbilityCell': {frozenset({'DoubleJump', ('HC', 2)})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'DoubleJump', ('HC', 1)}), frozenset({'ChargeJump', ('HC', 1)}), frozenset({'Glide', 'Stomp', ('HC', 1)}), frozenset({'Glide', 'WallJump', ('HC', 1)}), frozenset({'Dash', ('AC', 3), ('HC', 1)})}, 'LeftGumoHideoutSwim': {frozenset({'Free'})}, 'SorrowSpikeKeystone': {frozenset({'Climb', 'DoubleJump', ('HC', 2)}), frozenset({'ChargeJump', 'WallJump', ('HC', 2)}), frozenset({'Climb', 'ChargeJump', ('HC', 2)}), frozenset({'DoubleJump', 'WallJump', ('HC', 2)})}, 'SorrowHiddenKeystone': {frozenset({'Climb', 'Bash', ('HC', 2)}), frozenset({'Bash', 'WallJump', ('HC', 2)})}, 'SorrowHealthCell': {frozenset({'ChargeJump', 'DoubleJump', 'WallJump', ('HC', 2)})}, 'MistyFrogNookExp': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({('HC', 4), 'Dash', 'WallJump'})}, 'MistyPostClimbSpikeCave': {frozenset({'Glide', ('HC', 1)})}, 'MistyMortarCorridorUpperExp': {frozenset({'ChargeJump', ('HC', 1)}), frozenset({'Bash', ('HC', 1)})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Grenade', 'Bash', ('HC', 1)}), frozenset({'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({'Dash', ('AC', 3), ('HC', 1)}), frozenset({('HC', 4), 'Bash'})}, 'GrottoEnergyDoorSwim': {frozenset({('EC', 2)})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'Climb', 'DoubleJump'})}, 'LeftGrottoTeleporterExp': {frozenset({('HC', 4), 'WallJump'}), frozenset({'Glide', 'DoubleJump', ('HC', 1)}), frozenset({'Climb', 'Glide', ('HC', 1)}), frozenset({'ChargeJump', ('HC', 1)}), frozenset({'Climb', ('HC', 4)}), frozenset({'Glide', 'WallJump', ('HC', 1)})}, 'BelowGrottoTeleporterHealthCell': {frozenset({'Bash', ('HC', 2)})}, 'OutsideForlornWaterExp': {frozenset({('HC', 1)}), frozenset({'Stomp', ('HC', -1)})}, 'HoruR1HangingExp': {frozenset({'ChargeJump', ('HC', 2)})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', ('HC', 0)}), frozenset({('HC', 0), 'Climb', 'Dash', 'Water', 'Grenade', 'Stomp', 'DoubleJump', ('AC', 3)}), frozenset({'Climb', 'Dash', ('HC', 1), 'Grenade', 'Stomp', 'DoubleJump', ('AC', 3)}), frozenset({('HC', 0), 'Water', 'Grenade', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({('AC', 6), 'Dash', ('EC', 3), 'Grenade', ('HC', 1)}), frozenset({('HC', 1), 'Grenade', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'ChargeJump', ('HC', 1)})}, 'GroveSpiderWaterSwim': {frozenset({'Bash', ('HC', 2)}), frozenset({('HC', 3)})}, 'GladesGrenadePool': {frozenset({'Grenade', ('HC', 3)}), frozenset({'Grenade', 'Stomp', ('HC', 2)})}, 'GladesMainPool': {frozenset({'Bash', ('HC', 0)}), frozenset({('HC', 1)}), frozenset({'Stomp', ('HC', 0)})}, 'GladesMainPoolDeep': {frozenset({('HC', 4)})}, 'SwampEntranceSwim': {frozenset({'Free'})}, 'InnerSwampStompExp': {frozenset({'Dash', 'ChargeJump', ('AC', 3)}), frozenset({'Stomp'}), frozenset({'Grenade', 'Bash', 'ChargeJump'})}, 'TopGinsoLeftLowerExp': {frozenset({('HC', 2)})}, 'TopGinsoRightPlant': {frozenset({'ChargeFlame', 'DoubleJump', 'WallJump', ('HC', 0)}), frozenset({'Climb', ('HC', 0), 'DoubleJump', 'ChargeFlame'})}, 'UpperGinsoLowerKeystone': {frozenset({'GinsoKey', ('HC', 2)})}, 'UpperGinsoRightKeystone': {frozenset({'GinsoKey', 'DoubleJump', 'WallJump', ('HC', 2)})}, 'UpperSorrowRightKeystone': {frozenset({('AC', 6), 'Dash', 'ChargeJump', ('HC', 2)})}, 'UpperSorrowLeftKeystone': {frozenset({'ChargeJump', ('HC', 2)})}, 'ValleyRightSwimExp': {frozenset({('HC', 1)})}, 'ValleyRightFastStomplessCell': {frozenset({'ChargeJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', 'ChargeJump', ('HC', 1)}), frozenset({'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'ValleyRightExp': {frozenset({'ChargeJump', 'DoubleJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'ValleyMainFACS': {frozenset({'WallJump', 'Dash', ('HC', 1), 'ChargeJump', ('AC', 3)})}, 'WilhelmExp': {frozenset({'ChargeJump', ('HC', 2)})}}, 'master-lure': {'UpperSorrowSpikeExp': {frozenset({'Bash'})}, 'UpperSorrowFarLeftKeystone': {frozenset({'Bash'})}, 'UpperSorrowRightKeystone': {frozenset({'Bash'})}, 'UpperSorrowFarRightKeystone': {frozenset({'Bash'})}, 'UpperSorrowLeftKeystone': {frozenset({'Bash'})}, 'ForlornKeystone2': {frozenset({'ForlornKey', 'Bash'})}, 'ForlornEscape': {frozenset({'Bash'})}, 'ForlornKeystone3': {frozenset({'ForlornKey', 'Bash'})}, 'GroveWaterStompAbilityCell': {frozenset({('AC', 12)}), frozenset({('HC', 2)})}, 'SwampTeleporterAbilityCell': {frozenset({'Bash'})}, 'WallJumpAreaExp': {frozenset({'Bash'})}, 'WallJumpAreaEnergyCell': {frozenset({'Bash'})}, 'SorrowHealthCell': {frozenset({'Glide', 'Stomp', 'WallJump'}), frozenset({'Glide', 'Stomp', 'DoubleJump'}), frozenset({'Climb', 'Glide', 'Stomp'})}, 'KuroPerchExp': {frozenset({'Bash'})}, 'LeftGrottoTeleporterExp': {frozenset({'Bash'})}, 'InnerSwampDrainExp': {frozenset({'Bash', 'Water'})}, 'InnerSwampStompExp': {frozenset({'Bash', 'Water'}), frozenset({'Bash', ('HC', 0)})}}, 'master-dboost': {'UpperSorrowSpikeExp': {frozenset({('AC', 12), 'Dash', 'Grenade', 'Bash', ('HC', 1)}), frozenset({('AC', 12), 'Grenade', 'Bash', 'DoubleJump', ('HC', 1)}), frozenset({('EC', 2), 'Dash', ('AC', 12), ('HC', 1)}), frozenset({('AC', 12), 'Dash', 'ChargeJump', ('HC', 1)}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'UpperSorrowFarLeftKeystone': {frozenset({('AC', 12), 'Dash', ('HC', 1), 'Grenade', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({('AC', 12), 'Dash', ('HC', 1), 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({('HC', 4), ('AC', 12), 'Climb', 'Grenade', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({('AC', 12), 'Climb', 'Dash', 'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 12), 'Climb', 'ChargeJump', 'DoubleJump', ('HC', 7)}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', 'WallJump', ('HC', 7)}), frozenset({('AC', 12), 'Climb', 'Dash', 'Grenade', 'Bash', 'DoubleJump', ('HC', 1)}), frozenset({('HC', 4), ('AC', 12), 'Grenade', 'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', ('AC', 12), ('HC', 0), 'WallJump'})}, 'HoruR1EnergyCell': {frozenset({('AC', 12), 'WallJump', ('HC', 1)}), frozenset({'Climb', ('AC', 12), ('HC', 1)})}, 'HoruR4DrainedExp': {frozenset({('HC', 8)}), frozenset({('AC', 12), ('HC', 6)})}, 'HoruL1': {frozenset({('EC', 1), ('AC', 12), 'Climb', ('HC', 2), 'Stomp', 'DoubleJump'}), frozenset({('AC', 12), 'Climb', ('EC', 2), 'Stomp', 'DoubleJump', ('HC', 1)}), frozenset({('HC', 4), ('AC', 12), 'Climb', 'Stomp', 'DoubleJump'}), frozenset({('AC', 12), ('HC', 1), 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Bash', 'Stomp', ('HC', 2)}), frozenset({'Stomp', 'ChargeJump', ('HC', 2)})}, 'HoruL3': {frozenset({('HC', 3), ('AC', 12), 'Climb', 'Dash', ('EC', 2), 'Glide', 'DoubleJump'}), frozenset({('HC', 0), ('AC', 12), 'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'ChargeFlame', ('HC', 0), ('AC', 12), 'ChargeJump', 'DoubleJump'}), frozenset({('EC', 1), ('AC', 12), 'Climb', 'Dash', 'Glide', 'Stomp', 'DoubleJump', ('HC', 1)}), frozenset({'Climb', 'Glide', 'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({('HC', 0), ('AC', 12), 'Stomp', 'ChargeJump', 'DoubleJump'})}, 'LeftSorrowAbilityCell': {frozenset({('AC', 12), 'ChargeJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', ('AC', 12), 'ChargeJump', ('HC', 1)})}, 'LeftSorrowKeystone3': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'LeftSorrowKeystone4': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'LeftSorrowEnergyCell': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'LostGroveLongSwim': {frozenset({('HC', 3), ('AC', 12)}), frozenset({('HC', 9)})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Stomp', ('HC', 1)})}, 'SorrowLowerLeftKeystone': {frozenset({('AC', 12), 'ChargeJump', ('HC', 7)})}, 'MistyFrogNookExp': {frozenset({'DoubleJump', ('HC', 1)})}, 'MistyPostClimbSpikeCave': {frozenset({'Bash', ('HC', 1)}), frozenset({'DoubleJump', ('HC', 8)})}, 'MistyMortarCorridorHiddenExp': {frozenset({('HC', 7)}), frozenset({('HC', 4), ('AC', 12)}), frozenset({'DoubleJump', ('HC', 1)})}, 'LeftGrottoTeleporterExp': {frozenset({'DoubleJump', ('HC', 1)})}, 'OutsideForlornWaterExp': {frozenset({('AC', 12), ('HC', -1)})}, 'HoruR1HangingExp': {frozenset({('AC', 12), 'ChargeJump', ('HC', 1)})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'DoubleJump', ('HC', 2)}), frozenset({'Water', ('HC', 2), 'Grenade', 'Stomp', 'DoubleJump'}), frozenset({'Grenade', 'Stomp', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 12), 'Water', ('HC', 2), 'Grenade', 'DoubleJump'})}, 'GroveSpiderWaterSwim': {frozenset({('HC', 2)}), frozenset({'Bash', ('AC', 12)}), frozenset({('AC', 12), ('HC', 1)})}, 'GladesGrenadePool': {frozenset({'Grenade', ('HC', 2)})}, 'GladesMainPool': {frozenset({('HC', 0)})}, 'InnerSwampDrainExp': {frozenset({('HC', 4), 'Dash', ('AC', 12), 'WallJump'}), frozenset({('HC', 4), 'Bash', ('AC', 12)}), frozenset({('HC', 4), ('AC', 12), 'Grenade', 'Glide', 'Stomp', 'WallJump'}), frozenset({'Climb', ('HC', 4), 'ChargeJump', ('AC', 12)}), frozenset({'ChargeFlame', ('HC', 4), ('AC', 12), 'Glide', 'Stomp', 'WallJump'}), frozenset({('HC', 4), ('AC', 12), 'DoubleJump'}), frozenset({'Climb', 'Dash', ('HC', 4), ('AC', 12)})}, 'TopGinsoLeftUpperExp': {frozenset({('HC', 0), 'Glide', 'DoubleJump'}), frozenset({('HC', 0), 'Dash', 'DoubleJump'})}, 'TopGinsoRightPlant': {frozenset({'ChargeFlame', 'DoubleJump', ('HC', 0)}), frozenset({'Grenade', 'DoubleJump', ('HC', 0)})}, 'UpperGinsoRightKeystone': {frozenset({('HC', 0), ('AC', 12), 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoUpperRightKeystone': {frozenset({('AC', 12), 'GinsoKey', 'DoubleJump', ('HC', 2)})}, 'UpperGinsoUpperLeftKeystone': {frozenset({('AC', 12), 'GinsoKey', 'DoubleJump', ('HC', 2)})}, 'UpperSorrowRightKeystone': {frozenset({('HC', 4), 'ChargeJump', 'DoubleJump', ('AC', 12)}), frozenset({('AC', 12), 'Grenade', 'Bash', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 12), 'Dash', 'ChargeJump', ('HC', 1)}), frozenset({('AC', 12), 'ChargeJump', ('HC', 7)})}, 'UpperSorrowFarRightKeystone': {frozenset({('HC', 4), 'Dash', 'ChargeJump', ('AC', 12)}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 7)}), frozenset({('HC', 4), ('AC', 12), 'Grenade', 'Bash', 'DoubleJump'})}, 'UpperSorrowLeftKeystone': {frozenset({('AC', 12), 'ChargeJump', ('HC', 1)})}, 'ValleyEntryGrenadeLongSwim': {frozenset({'Grenade', 'Bash', ('HC', 10)}), frozenset({'Grenade', ('HC', 11)}), frozenset({'Grenade', ('HC', 4), ('AC', 12)})}, 'ValleyRightFastStomplessCell': {frozenset({'Climb', ('HC', 4), ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump', ('HC', 2)})}, 'ValleyRightExp': {frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'WilhelmExp': {frozenset({('AC', 12), 'ChargeJump', ('HC', 1)})}}, 'standard-lure': {'DeathGauntletExp': {frozenset({'Bash'})}, 'DeathGauntletStompSwim': {frozenset({'Water'})}, 'GladesLaser': {frozenset({'Bash'})}, 'HoruFieldsHealthCell': {frozenset({'Free'})}, 'HollowGroveTreeAbilityCell': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}, 'HoruL2': {frozenset({'Stomp', 'DoubleJump', 'Bash'})}, 'LeftSorrowKeystone1': {frozenset({'Bash'})}, 'MistyEntranceStompExp': {frozenset({'Bash'})}, 'MistyAbilityCell': {frozenset({'Bash'})}, 'GrottoSwampDrainAccessPlant': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'Grenade'})}, 'SorrowMap': {frozenset({'Mapstone'})}, 'FronkeyWalkRoof': {frozenset({'Bash'})}, 'ValleyRightFastStomplessCell': {frozenset({'Bash'})}, 'WilhelmExp': {frozenset({'Bash', 'WallJump'})}, 'KuroPerchExp': {frozenset({'HoruKey'})}}, 'casual-dboost': {'DoubleJumpSkillTree': {frozenset({'Bash', ('HC', 0)}), frozenset({'Climb', ('HC', 0)}), frozenset({'ChargeJump', ('HC', 0)})}, 'DoubleJumpAreaExp': {frozenset({'Grenade', 'Bash', ('HC', 0)}), frozenset({'ChargeJump', ('HC', 0), 'Water'}), frozenset({('HC', -1), 'ChargeJump', 'WallJump'}), frozenset({'Bash', ('HC', 0), 'Water'}), frozenset({'Bash', 'WallJump', ('HC', -1)})}, 'GrenadeAreaExp': {frozenset({'ChargeJump'})}, 'GumoHideoutCrusherKeystone': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'GumoHideoutRedirectAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'WallJump'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'ChargeJump', 'Water'})}, 'SpiderSacHealthCell': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'InnerSwampSwimRightKeystone': {frozenset({'Climb'}), frozenset({'WallJump'})}, 'SpiritCavernsTopLeftKeystone': {frozenset({'ChargeJump'}), frozenset({'Bash'})}}, 'standard-dboost': {'DoubleJumpSkillTree': {frozenset({'Dash', ('HC', 0)})}, 'DoubleJumpAreaExp': {frozenset({'Dash', 'ChargeJump', ('HC', 0)}), frozenset({('HC', 0), 'Bash', 'Dash'}), frozenset({'ChargeJump', ('HC', 0), ('AC', 3), ('EC', 1)}), frozenset({'Bash', ('HC', 0), ('AC', 3), ('EC', 1)}), frozenset({'Bash', ('HC', 1)}), frozenset({'ChargeJump', ('HC', 1)})}, 'ForlornKeystone3': {frozenset({'ForlornKey', 'ChargeJump', ('HC', 1)})}, 'LowerGinsoKeystone1': {frozenset({('HC', 0)})}, 'LowerGinsoKeystone2': {frozenset({'ChargeJump', ('HC', 0)})}, 'GumoHideoutMapstone': {frozenset({'ChargeJump', ('HC', 1)})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Dash', 'ChargeJump', ('HC', 1)})}, 'MistyAbilityCell': {frozenset({'DoubleJump', 'WallJump', ('HC', 1)})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'WallJump'})}, 'BelowGrottoTeleporterHealthCell': {frozenset({('HC', 0), 'Bash', 'DoubleJump'}), frozenset({'Bash', ('HC', 0), 'WallJump'}), frozenset({'ChargeJump', ('HC', 0)})}, 'BelowGrottoTeleporterPlant': {frozenset({'ChargeFlame', ('HC', 1)}), frozenset({'Grenade', ('HC', 1)})}, 'GrottoSwampDrainAccessPlant': {frozenset({'ChargeFlame', 'Glide', ('HC', 1)}), frozenset({'ChargeFlame', 'DoubleJump', ('HC', 1)}), frozenset({'ChargeFlame', 'ChargeJump', ('HC', 1)}), frozenset({'ChargeFlame', 'WallJump', ('HC', 1)})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', ('HC', 0), 'Water'})}, 'InnerSwampDrainExp': {frozenset({'Grenade', 'Bash', ('HC', 1), 'Water'})}, 'TopGinsoLeftLowerExp': {frozenset({('HC', 0), 'DoubleJump'}), frozenset({'ChargeJump', ('HC', 0)})}, 'TopGinsoLeftUpperExp': {frozenset({('HC', 0), 'Dash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Dash', 'DoubleJump', ('HC', 0)}), frozenset({'Climb', 'Glide', 'DoubleJump', ('HC', 0)}), frozenset({('HC', 0), 'Glide', 'DoubleJump', 'WallJump'})}, 'TopGinsoRightPlant': {frozenset({'Grenade', 'DoubleJump', 'WallJump', ('HC', 0)}), frozenset({'Climb', 'Grenade', 'DoubleJump', ('HC', 0)})}, 'UpperGinsoLowerKeystone': {frozenset({'Bash', 'GinsoKey', ('HC', 0)}), frozenset({'GinsoKey', ('HC', 0), 'ChargeJump'}), frozenset({('HC', 0), 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoRightKeystone': {frozenset({'GinsoKey', ('HC', 0), 'ChargeJump'})}, 'UpperGinsoUpperRightKeystone': {frozenset({'GinsoKey', ('HC', 0), 'ChargeJump'})}, 'UpperGinsoUpperLeftKeystone': {frozenset({'GinsoKey', ('HC', 0), 'ChargeJump'})}}, 'standard-core': {'DoubleJumpAreaExp': {frozenset({'ChargeJump', 'WallJump'})}, 'ForlornKeystone2': {frozenset({'ForlornKey', 'Dash', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'ForlornKey', 'Dash', 'WallJump'}), frozenset({'Climb', 'ForlornKey', 'Dash', 'DoubleJump'}), frozenset({'Glide', 'ForlornKey', 'Climb', 'Dash'})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', 'Dash', 'WallJump', 'Open'}), frozenset({'Climb', 'ForlornKey', 'Dash', 'Open'})}, 'LowerGinsoKeystone1': {frozenset({'Grenade', 'Bash'})}, 'LowerGinsoKeystone2': {frozenset({'Grenade', 'Bash'})}, 'GladesLaserGrenade': {frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Grenade', 'Climb', 'Bash'}), frozenset({'Climb', 'Grenade', 'Glide', 'ChargeJump', 'DoubleJump'})}, 'GrenadeSkillTree': {frozenset({'Grenade', 'Bash'})}, 'GrenadeAreaExp': {frozenset({'Dash', 'DoubleJump'})}, 'GrenadeAreaAbilityCell': {frozenset({'Grenade', 'Bash'})}, 'GumoHideoutMapstone': {frozenset({'Climb'}), frozenset({'Grenade', 'Bash'})}, 'GumoHideoutRedirectAbilityCell': {frozenset({'Grenade', 'Bash'})}, 'SwampTeleporterAbilityCell': {frozenset({'Grenade', 'Bash', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Glide'})}, 'HoruFieldsHiddenExp': {frozenset({'Bash'})}, 'HoruLavaDrainedLeftExp': {frozenset({'Open', 'Dash', 'DoubleJump'})}, 'HoruL4LowerExp': {frozenset({'Climb', 'Stomp'})}, 'HoruR1EnergyCell': {frozenset({'Grenade', 'Bash'})}, 'HoruR3Plant': {frozenset({'ChargeFlame'})}, 'HoruR4DrainedExp': {frozenset({'Grenade', 'Bash', 'Climb'})}, 'HoruL1': {frozenset({'Glide', 'ChargeJump', 'Stomp', 'Bash'})}, 'HoruL3': {frozenset({'ChargeFlame', 'Bash', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Stomp'}), frozenset({'Glide', 'Bash', 'ChargeFlame', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'}), frozenset({'Glide', 'Bash', 'Climb', 'ChargeFlame'}), frozenset({'Grenade', 'Bash', 'ChargeFlame'})}, 'FarLeftGumoHideoutExp': {frozenset({'Climb', 'Bash', 'Grenade'})}, 'LeftSorrowKeystone1': {frozenset({'Dash'})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Dash', 'DoubleJump'})}, 'LowerBlackrootGrenadeThrow': {frozenset({'ChargeJump', 'DoubleJump'})}, 'GumoHideoutRightHangingExp': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'})}, 'SorrowSpikeKeystone': {frozenset({'Climb', 'Dash', 'DoubleJump'}), frozenset({'Dash', 'DoubleJump', 'WallJump'})}, 'SorrowHiddenKeystone': {frozenset({'Climb', 'Bash', 'Dash', 'DoubleJump'}), frozenset({'Bash', 'Dash', 'DoubleJump', 'WallJump'})}, 'SorrowHealthCell': {frozenset({'Bash', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'})}, 'SpiritCavernsAbilityCell': {frozenset({'DoubleJump', 'WallJump'})}, 'MistyFrogNookExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Bash'})}, 'MistyPostClimbSpikeCave': {frozenset({'Glide', 'Bash'})}, 'MistyMortarCorridorUpperExp': {frozenset({'Grenade', 'Bash'})}, 'OuterSwampHealthCell': {frozenset({'Climb', 'DoubleJump'})}, 'HoruR1HangingExp': {frozenset({'Grenade', 'Bash'})}, 'HoruR2': {frozenset({'Glide', 'Stomp', 'Climb', 'Bash'}), frozenset({'Glide', 'Stomp', 'ChargeJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'WallJump', 'Bash'})}, 'StompAreaExp': {frozenset({'Climb', 'ChargeJump'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', 'DoubleJump', 'Water'})}, 'GroveAboveSpiderWaterExp': {frozenset({'Bash', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Bash', 'ChargeJump'})}, 'GroveAboveSpiderWaterEnergyCell': {frozenset({'Dash', 'Grenade', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Grenade', 'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'AboveChargeFlameTreeExp': {frozenset({'Glide', 'Bash', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb'})}, 'GladesGrenadeTree': {frozenset({'Grenade', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Glide', 'Climb', 'Wind'}), frozenset({'Grenade', 'Glide', 'WallJump', 'Wind'})}, 'InnerSwampSwimRightKeystone': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'})}, 'TopGinsoLeftLowerExp': {frozenset({'Bash'})}, 'UpperGinsoRedirectLowerExp': {frozenset({'Climb', 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoRightKeystone': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Glide', 'GinsoKey', 'ChargeJump'}), frozenset({'GinsoKey', 'DoubleJump', 'ChargeJump'})}, 'UpperGinsoUpperRightKeystone': {frozenset({'Bash', 'GinsoKey'}), frozenset({'GinsoKey', 'DoubleJump', 'ChargeJump'})}, 'UpperGinsoUpperLeftKeystone': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Glide', 'GinsoKey', 'ChargeJump'}), frozenset({'GinsoKey', 'DoubleJump', 'ChargeJump'})}, 'UpperGinsoEnergyCell': {frozenset({'Climb', 'GinsoKey', 'ChargeJump'})}, 'GrottoLasersRoofExp': {frozenset({'Climb', 'DoubleJump'})}, 'SpiritCavernsTopLeftKeystone': {frozenset({'ChargeJump'}), frozenset({'Bash'})}, 'ValleyRightBirdStompCell': {frozenset({'Stomp', 'DoubleJump'}), frozenset({'Climb', 'Stomp'}), frozenset({'Stomp', 'WallJump'})}, 'ValleyThreeBirdAbilityCell': {frozenset({'Dash', 'DoubleJump'})}, 'KuroPerchExp': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-lure': {'ForlornKeystone1': {frozenset({'ForlornKey', 'Bash'})}, 'GumoHideoutMiniboss': {frozenset({'Bash'})}, 'GroveWaterStompAbilityCell': {frozenset({'Bash', 'Water'})}, 'SorrowHealthCell': {frozenset({'Grenade', 'Glide', 'Stomp', 'Bash'}), frozenset({('AC', 6), 'Dash', ('EC', 2), 'Glide', 'Stomp'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump'}), frozenset({'Glide', 'Stomp', 'ChargeJump'})}}, 'gjump': {'GladesLaserGrenade': {frozenset({'Grenade', 'Climb', 'ChargeJump'})}, 'SwampTeleporterAbilityCell': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'HoruFieldsEnergyCell': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'HoruR4LaserExp': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'HoruL3': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'SorrowSpikeKeystone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'SorrowHiddenKeystone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'SorrowLowerLeftKeystone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'KuroPerchExp': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'MistyMortarCorridorUpperExp': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Climb', 'ChargeJump', 'Water'})}, 'SorrowMapstone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'GroveAboveSpiderWaterExp': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'UpperSorrowLeftKeystone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'ValleyThreeBirdAbilityCell': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'insane': {'GrenadeSkillTree': {frozenset({'WallJump'})}, 'ValleyRightBirdStompCell': {frozenset({'Bash'})}}, 'timed-level': {'LowerBlackrootGrenadeThrow': {frozenset({'Free'})}, 'SpiderSacEnergyDoor': {frozenset({('EC', 2)})}}} +location_rules = {'casual-core': {'AboveChargeJumpAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'BashSkillTree': {frozenset({'GinsoKey'})}, 'BashAreaExp': {frozenset({'Bash', 'GinsoKey'}), frozenset({'GinsoKey', 'ChargeJump'})}, 'DashAreaOrbRoomExp': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DashAreaAbilityCell': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DashAreaRoofExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'BlackrootBoulderExp': {frozenset({'Stomp'})}, 'BlackrootMap': {frozenset({'MapStone', 'ChargeJump'}), frozenset({'Climb', 'MapStone', 'DoubleJump'}), frozenset({'MapStone', 'WallJump'}), frozenset({'Grenade', 'Bash', 'MapStone'})}, 'ChargeFlameAreaPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'DashAreaMapstone': {frozenset({'Dash'})}, 'DashAreaPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'DeathGauntletExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DeathGauntletStompSwim': {frozenset({'Stomp', 'Water'})}, 'DeathGauntletEnergyCell': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DeathGauntletSwimEnergyDoor': {frozenset({('EC', 4)})}, 'DeathGauntletRoofPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'DoubleJumpSkillTree': {frozenset({'Glide'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'Bash', 'Grenade'}), frozenset({'DoubleJump'})}, 'DoubleJumpAreaExp': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Climb', 'Bash', 'Grenade'}), frozenset({'Bash', 'WallJump', 'Water'}), frozenset({'ChargeJump', 'WallJump', 'Water'})}, 'ForlornHiddenSpiderExp': {frozenset({'ForlornKey', 'ChargeJump'}), frozenset({'ForlornKey', 'Bash'})}, 'ForlornKeystone1': {frozenset({'ForlornKey', 'ChargeJump'}), frozenset({'ForlornKey'}), frozenset({'Grenade', 'ForlornKey', 'Bash'}), frozenset({'ForlornKey', 'DoubleJump', 'Bash'})}, 'ForlornKeystone2': {frozenset({'ForlornKey', 'ChargeJump'}), frozenset({'Grenade', 'ForlornKey', 'Bash'}), frozenset({'Glide', 'ForlornKey', 'DoubleJump', 'WallJump'}), frozenset({'ForlornKey'}), frozenset({'Climb', 'ForlornKey', 'Glide', 'DoubleJump'})}, 'ForlornEntranceExp': {frozenset({'Grenade', 'ForlornKey', 'Bash'}), frozenset({'ForlornKey', 'ChargeJump', 'Open'}), frozenset({'ForlornKey', 'ChargeJump', 'DoubleJump'}), frozenset({'ForlornKey', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'ForlornKey', 'WallJump', 'Open'}), frozenset({'ForlornKey', 'DoubleJump', 'Open'}), frozenset({'Climb', 'ForlornKey', 'DoubleJump'}), frozenset({'ForlornKey', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'ForlornKey', 'ChargeJump'}), frozenset({'Glide', 'ForlornKey', 'Climb', 'Open'})}, 'ForlornEscape': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'ForlornMap': {frozenset({'ForlornKey', 'MapStone'})}, 'ForlornKeystone4': {frozenset({'ForlornKey'}), frozenset({'Grenade', 'ForlornKey', 'WallJump', 'Bash'}), frozenset({'ForlornKey', 'ChargeJump', 'WallJump'}), frozenset({'Grenade', 'ForlornKey', 'Climb', 'Bash'}), frozenset({'Climb', 'ForlornKey', 'ChargeJump'})}, 'ForlornKeystone3': {frozenset({'Grenade', 'ForlornKey', 'Climb', 'Bash'}), frozenset({'Glide', 'ForlornKey', 'ChargeJump'}), frozenset({'ForlornKey'}), frozenset({'ForlornKey', 'ChargeJump', 'DoubleJump'})}, 'ForlornPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'LowerGinsoKeystone1': {frozenset({'DoubleJump'}), frozenset({'Glide'})}, 'LowerGinsoKeystone2': {frozenset({'DoubleJump'}), frozenset({'Glide'})}, 'LowerGinsoKeystone3': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'LowerGinsoKeystone4': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'GladesLaser': {frozenset({'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'GladesLaserGrenade': {frozenset({'Grenade', 'Climb', 'ChargeJump', 'Bash'}), frozenset({'Grenade', 'Bash', 'DoubleJump', 'WallJump'})}, 'GladesMap': {frozenset({'MapStone'})}, 'GrenadeSkillTree': {frozenset({'Climb', 'Dash'}), frozenset({'Grenade', 'Dash', 'Bash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Dash', 'ChargeJump'})}, 'GrenadeAreaExp': {frozenset({'Climb', 'Dash', 'Glide'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide', 'Dash', 'Bash'}), frozenset({'Glide', 'Dash', 'WallJump'})}, 'GrenadeAreaAbilityCell': {frozenset({'Grenade', 'Dash', 'Bash'}), frozenset({'Grenade', 'Dash', 'ChargeJump'})}, 'GumoHideoutMap': {frozenset({'MapStone'})}, 'GumoHideoutRightHangingExp': {frozenset({'Glide', 'Wind'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'Glide'}), frozenset({'ChargeJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Glide', 'WallJump'})}, 'GumoHideoutMapstone': {frozenset({'Glide'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'Bash', 'Grenade'}), frozenset({'DoubleJump'})}, 'GumoHideoutMiniboss': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'GumoHideoutEnergyCell': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'GumoHideoutCrusherExp': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'GumoHideoutCrusherKeystone': {frozenset({'Climb'}), frozenset({'WallJump'})}, 'GumoHideoutRedirectAbilityCell': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Glide'})}, 'GumoHideoutRedirectPlant': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'ChargeFlame'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Climb', 'Grenade'})}, 'GumoHideoutRedirectEnergyCell': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'Glide'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'DoubleJump'})}, 'GumoHideoutRedirectExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'Glide'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'DoubleJump'})}, 'GroveWaterStompAbilityCell': {frozenset({'Stomp', 'Water'})}, 'HoruFieldsHealthCell': {frozenset({'Stomp'})}, 'HollowGroveTreePlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'HollowGroveTreeAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Glide', 'Wind'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'HollowGroveMap': {frozenset({'MapStone'})}, 'HollowGroveMapPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'SwampTeleporterAbilityCell': {frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash', 'Glide', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Glide', 'WallJump'}), frozenset({'Climb', 'Glide', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb', 'Glide'}), frozenset({'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'DoorWarpExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'HoruFieldsPlant': {frozenset({'Grenade', 'Glide', 'ChargeJump'}), frozenset({'ChargeFlame', 'Glide', 'ChargeJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'ChargeFlame', 'Bash'}), frozenset({'Climb', 'ChargeJump', 'Grenade'}), frozenset({'Climb', 'ChargeJump', 'ChargeFlame'})}, 'HoruFieldsEnergyCell': {frozenset({'Glide', 'Bash'}), frozenset({'Glide', 'ChargeJump', 'DoubleJump'}), frozenset({'Bash', 'DoubleJump'})}, 'HoruFieldsHiddenExp': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'HoruFieldsAbilityCell': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump'})}, 'HoruLavaDrainedLeftExp': {frozenset({'Open', 'Bash'}), frozenset({'Glide', 'Open', 'DoubleJump'}), frozenset({'Open', 'ChargeJump'})}, 'HoruLavaDrainedRightExp': {frozenset({'Glide', 'Open', 'Bash'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'}), frozenset({'Grenade', 'Open', 'Bash'}), frozenset({'DoubleJump'}), frozenset({'Glide', 'Open', 'ChargeJump'})}, 'HoruL4': {frozenset({'Stomp'})}, 'HoruL4LowerExp': {frozenset({'Grenade', 'Bash', 'Stomp'}), frozenset({'Stomp', 'WallJump'}), frozenset({'Stomp', 'ChargeJump'})}, 'HoruL4ChaseExp': {frozenset({'Free'})}, 'HoruMap': {frozenset({'MapStone'})}, 'HoruR1EnergyCell': {frozenset({'Climb', 'Glide', 'DoubleJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'Bash', 'Grenade'}), frozenset({'Glide', 'WallJump'})}, 'HoruR3Plant': {frozenset({'Grenade'})}, 'HoruR4DrainedExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Glide', 'DoubleJump'})}, 'HoruR4LaserExp': {frozenset({'Bash', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'InnerSwampDrainExp': {frozenset({'Grenade', 'Bash', 'WallJump', 'Water'}), frozenset({'Climb', 'ChargeJump', 'Water'}), frozenset({'Glide'}), frozenset({'Climb', 'Bash', 'Grenade', 'Water'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeFlame', 'Water', 'Glide', 'Stomp', 'WallJump'}), frozenset({'DoubleJump', 'WallJump', 'Water'}), frozenset({'Grenade', 'Glide', 'Water', 'Bash'}), frozenset({'Glide', 'ChargeJump', 'DoubleJump', 'Water'}), frozenset({'Grenade', 'Bash', 'DoubleJump', 'Water'}), frozenset({'DoubleJump'}), frozenset({'Water', 'Grenade', 'Glide', 'Stomp', 'WallJump'}), frozenset({'Climb', 'DoubleJump', 'Water'}), frozenset({'Climb', 'Dash', 'Glide', 'Water'})}, 'HoruL1': {frozenset({'Grenade', 'Glide', 'Stomp', 'Bash'}), frozenset({'Glide', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Bash', 'Stomp', 'DoubleJump'})}, 'HoruL2': {frozenset({'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Stomp', 'Bash'}), frozenset({'Stomp', 'ChargeJump'})}, 'HoruL3': {frozenset({'Glide', 'Bash', 'Stomp', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb', 'Stomp'}), frozenset({'Stomp', 'DoubleJump', 'Bash'})}, 'WallJumpAreaExp': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'WallJumpAreaEnergyCell': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'LeftGumoHideoutUpperPlant': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Climb', 'ChargeFlame'}), frozenset({'Grenade'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'ChargeFlame', 'DoubleJump'})}, 'FarLeftGumoHideoutExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'DoubleJump'})}, 'LeftSorrowAbilityCell': {frozenset({'Glide', 'Bash'}), frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Glide', 'DoubleJump', 'WallJump'})}, 'LeftSorrowGrenade': {frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Grenade', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash', 'Glide'})}, 'LeftSorrowPlant': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'ChargeFlame', 'DoubleJump', 'WallJump'}), frozenset({'Grenade'})}, 'LeftSorrowKeystone1': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'})}, 'LeftSorrowKeystone2': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'})}, 'LeftSorrowKeystone3': {frozenset({'Glide'})}, 'LeftSorrowKeystone4': {frozenset({'Glide'})}, 'LeftSorrowEnergyCell': {frozenset({'Glide'})}, 'LostGroveLongSwim': {frozenset({'Water'})}, 'LostGroveHiddenExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'LostGroveTeleporter': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'LowerBlackrootAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Grenade', 'Dash', 'Bash'})}, 'LowerBlackrootLaserExp': {frozenset({'Grenade', 'Dash', 'Bash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Dash', 'ChargeJump'}), frozenset({'Climb', 'Dash', 'DoubleJump'})}, 'LowerBlackrootGrenadeThrow': {frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'Climb', 'Grenade'}), frozenset({'Grenade', 'Glide'}), frozenset({'Grenade', 'DoubleJump'})}, 'LowerGinsoHiddenExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'LowerGinsoPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'LeftGumoHideoutLowerPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'GumoHideoutLeftHangingExp': {frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'LeftGumoHideoutExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'LeftGumoHideoutHealthCell': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'ChargeJump'})}, 'LeftGumoHideoutSwim': {frozenset({'Water'})}, 'SorrowSpikeKeystone': {frozenset({'Glide'}), frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'})}, 'SorrowHiddenKeystone': {frozenset({'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'}), frozenset({'Glide'})}, 'SorrowHealthCell': {frozenset({'Glide', 'ChargeJump', 'Bash'})}, 'SorrowLowerLeftKeystone': {frozenset({'Glide'})}, 'SpiritCavernsKeystone2': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'SpiritCavernsAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Bash'})}, 'LowerValleyMapstone': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'KuroPerchExp': {frozenset({'Glide', 'Wind'}), frozenset({'Bash', 'OpenWorld'}), frozenset({'Glide'}), frozenset({'Bash'}), frozenset({'Glide', 'OpenWorld'}), frozenset({'Stomp'})}, 'ValleyMainPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'MistyGrenade': {frozenset({'Grenade'})}, 'MistyEntranceStompExp': {frozenset({'Stomp'})}, 'MistyEntranceTreeExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'MistyPostClimbAboveSpikePit': {frozenset({'Glide', 'Bash', 'WallJump'}), frozenset({'Climb', 'Bash', 'Glide'})}, 'GumonSeal': {frozenset({'Climb'}), frozenset({'DoubleJump'}), frozenset({'Bash'}), frozenset({'WallJump'})}, 'MistyFrogNookExp': {frozenset({'Grenade', 'Bash', 'DoubleJump'}), frozenset({'Glide', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'DoubleJump'})}, 'MistyPostClimbSpikeCave': {frozenset({'Glide', 'Bash', 'DoubleJump'})}, 'MistyAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'MistyMortarCorridorUpperExp': {frozenset({'Glide', 'Bash'})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Glide'})}, 'MistyPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'GrottoEnergyDoorSwim': {frozenset({('EC', 2), 'Water'})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'ChargeJump'}), frozenset({('EC', 2), 'Bash', 'Grenade'}), frozenset({('EC', 2), 'DoubleJump', 'WallJump'})}, 'AboveGrottoTeleporterExp': {frozenset({'Grenade', 'Bash'}), frozenset({'ChargeJump'}), frozenset({'Climb', 'Bash'}), frozenset({'DoubleJump'}), frozenset({'Bash', 'WallJump'})}, 'LeftGrottoTeleporterExp': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'})}, 'BelowGrottoTeleporterHealthCell': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump'})}, 'BelowGrottoTeleporterPlant': {frozenset({'ChargeFlame', 'Glide'}), frozenset({'Grenade', 'Glide'}), frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'Grenade', 'DoubleJump'})}, 'MoonGrottoStompPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'GrottoSwampDrainAccessExp': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Glide', 'Bash', 'DoubleJump'})}, 'GrottoSwampDrainAccessPlant': {frozenset({'Grenade', 'Stomp'}), frozenset({'ChargeFlame', 'Stomp', 'Climb', 'ChargeJump'}), frozenset({'ChargeFlame', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'ChargeFlame', 'Stomp', 'ChargeJump', 'Glide'}), frozenset({'ChargeFlame', 'Stomp', 'ChargeJump', 'DoubleJump'})}, 'OuterSwampStompExp': {frozenset({'Glide', 'Wind'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'OuterSwampHealthCell': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'OuterSwampMortarPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'OuterSwampGrenadeExp': {frozenset({'Grenade', 'ChargeJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Grenade', 'Climb'})}, 'OutsideForlornTreeExp': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'OutsideForlornWaterExp': {frozenset({'Water'})}, 'OutsideForlornCliffExp': {frozenset({'Glide'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Dash'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'HoruR1HangingExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Glide', 'DoubleJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'})}, 'HoruR2': {frozenset({'ChargeJump', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'Grenade', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump', 'Bash'})}, 'RightForlornPlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'StompAreaExp': {frozenset({'Bash'}), frozenset({'Stomp'})}, 'StompAreaRoofExp': {frozenset({'ChargeJump'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', 'Glide', 'Water'}), frozenset({'Climb', 'Water', 'Grenade', 'Glide', 'ChargeJump'}), frozenset({'Grenade', 'Stomp', 'ChargeJump', 'Water'}), frozenset({'Grenade', 'Bash', 'Stomp', 'Water'})}, 'SorrowMapstone': {frozenset({'Bash'})}, 'SorrowMap': {frozenset({'Bash', 'MapStone'}), frozenset({'Stomp', 'MapStone'})}, 'SpiderSacHealthCell': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump'}), frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'ChargeFlame', 'Climb', 'ChargeJump'}), frozenset({'Grenade', 'DoubleJump'})}, 'SpiderSacEnergyDoor': {frozenset({('EC', 4)})}, 'SpiderSacGrenadeDoor': {frozenset({'Grenade', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'GroveSpiderWaterSwim': {frozenset({'Water'})}, 'GroveAboveSpiderWaterExp': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Grenade', 'Bash'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'})}, 'GroveAboveSpiderWaterEnergyCell': {frozenset({'Grenade', 'Climb', 'ChargeJump', 'DoubleJump'})}, 'AboveChargeFlameTreeExp': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'})}, 'GladesGrenadePool': {frozenset({'Grenade', 'Water'})}, 'GladesGrenadeTree': {frozenset({'Grenade', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'GladesMainPool': {frozenset({'Water'})}, 'GladesMainPoolDeep': {frozenset({'Water'})}, 'FronkeyWalkRoof': {frozenset({'ChargeJump'}), frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash'})}, 'SunstonePlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'SwampMap': {frozenset({'MapStone'})}, 'SwampEntranceSwim': {frozenset({'Water'})}, 'SwampEntrancePlant': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'ChargeFlame', 'Climb'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Grenade', 'Climb'})}, 'InnerSwampStompExp': {frozenset({'Stomp', 'Water'})}, 'InnerSwampSwimRightKeystone': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'Bash'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Glide', 'WallJump'})}, 'TopGinsoLeftLowerExp': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'})}, 'TopGinsoLeftUpperExp': {frozenset({'ChargeJump'}), frozenset({'Bash'})}, 'TopGinsoRightPlant': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'UpperGinsoRedirectLowerExp': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Stomp', 'GinsoKey'})}, 'UpperGinsoRedirectUpperExp': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Stomp', 'GinsoKey'})}, 'UpperGinsoLowerKeystone': {frozenset({'Glide', 'Bash', 'GinsoKey'}), frozenset({'Bash', 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoRightKeystone': {frozenset({'Glide', 'Bash', 'GinsoKey'}), frozenset({'Bash', 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoUpperRightKeystone': {frozenset({'Bash', 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoUpperLeftKeystone': {frozenset({'Bash', 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoEnergyCell': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Stomp', 'GinsoKey'})}, 'GrottoLasersRoofExp': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'LeftGladesExp': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'UpperSorrowRightKeystone': {frozenset({'Glide'})}, 'UpperSorrowFarRightKeystone': {frozenset({'Glide'})}, 'UpperSorrowLeftKeystone': {frozenset({'Glide'})}, 'UpperSorrowSpikeExp': {frozenset({'Glide'})}, 'UpperSorrowFarLeftKeystone': {frozenset({'Glide'})}, 'SpiritCavernsTopLeftKeystone': {frozenset({'Climb', 'DoubleJump'}), frozenset({'WallJump'}), frozenset({'Climb', 'Glide'})}, 'ValleyThreeBirdAbilityCell': {frozenset({'Glide', 'Wind'}), frozenset({'Glide', 'OpenWorld', 'Wind'}), frozenset({'Bash', 'OpenWorld'}), frozenset({'ChargeJump', 'OpenWorld'}), frozenset({'Bash'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Climb', 'Glide', 'ChargeJump'})}, 'ValleyEntryGrenadeLongSwim': {frozenset({'Grenade', 'Water'})}, 'ValleyEntryTreePlant': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'ValleyForlornApproachGrenade': {frozenset({'Grenade'})}, 'ValleyMap': {frozenset({'Bash', 'MapStone'})}, 'ValleyRightSwimExp': {frozenset({'Water'})}, 'ValleyRightBirdStompCell': {frozenset({'Climb', 'ChargeJump'})}, 'ValleyRightFastStomplessCell': {frozenset({'Glide', 'Wind'})}, 'ValleyRightExp': {frozenset({'Bash'})}, 'ValleyMainFACS': {frozenset({'Climb', 'ChargeJump'})}, 'WilhelmExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash', 'Climb'})}}, 'dbash': {'AboveChargeJumpAbilityCell': {frozenset({'Bash'})}, 'GrenadeSkillTree': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Bash', 'DoubleJump'})}, 'GrenadeAreaExp': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Bash', 'DoubleJump'})}, 'HollowGroveTreeAbilityCell': {frozenset({'Bash'})}, 'HoruFieldsEnergyCell': {frozenset({'Bash'})}, 'HoruLavaDrainedRightExp': {frozenset({'Open', 'Bash'}), frozenset({'Bash'})}, 'HoruR4DrainedExp': {frozenset({'Bash'})}, 'HoruR4LaserExp': {frozenset({'Bash'})}, 'LeftSorrowGrenade': {frozenset({'Grenade', 'Bash'})}, 'GumoHideoutLeftHangingExp': {frozenset({'Bash'})}, 'GumoHideoutRightHangingExp': {frozenset({'Bash'})}, 'LeftGumoHideoutExp': {frozenset({'Bash'})}, 'LeftGumoHideoutHealthCell': {frozenset({'Bash'})}, 'SorrowSpikeKeystone': {frozenset({'Bash'})}, 'SorrowHiddenKeystone': {frozenset({'Bash'})}, 'SorrowHealthCell': {frozenset({'Bash'})}, 'AboveGrottoTeleporterExp': {frozenset({'Bash'})}, 'GrottoSwampDrainAccessExp': {frozenset({'Bash'})}, 'StompAreaRoofExp': {frozenset({'Bash'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', 'Water'})}, 'GroveAboveSpiderWaterExp': {frozenset({'Bash'})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Bash'})}, 'ValleyMainFACS': {frozenset({'Bash'})}, 'WilhelmExp': {frozenset({'Bash'})}}, 'expert-abilities': {'AboveChargeJumpAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'BashAreaExp': {frozenset({('AC', 6), 'Dash', 'GinsoKey'}), frozenset({('AC', 6), 'Dash', 'GinsoKey', 'DoubleJump', 'WallJump'})}, 'ChargeFlameAreaPlant': {frozenset({'Dash', ('AC', 6)})}, 'DashAreaPlant': {frozenset({'Dash', ('AC', 6)})}, 'DeathGauntletRoofPlant': {frozenset({'Dash', ('AC', 6)})}, 'DoubleJumpAreaExp': {frozenset({'Dash', ('AC', 6), ('EC', 1)})}, 'ForlornHiddenSpiderExp': {frozenset({'ForlornKey', ('AC', 6), 'Dash'})}, 'ForlornPlant': {frozenset({'Dash', ('AC', 6)})}, 'ForlornKeystone3': {frozenset({'ForlornKey', ('AC', 6), 'Dash', 'WallJump'}), frozenset({'Climb', 'ForlornKey', ('AC', 6), 'Dash'})}, 'GladesLaser': {frozenset({'Dash', ('AC', 6)})}, 'GladesLaserGrenade': {frozenset({('AC', 6), ('EC', 1), 'Dash', 'Grenade', 'DoubleJump', 'WallJump'}), frozenset({('AC', 6), ('EC', 1), 'Climb', 'Dash', 'Grenade', 'Glide', 'ChargeJump'}), frozenset({('AC', 6), ('EC', 2), 'Climb', 'Dash', 'Grenade', 'ChargeJump'})}, 'GrenadeSkillTree': {frozenset({'Dash', ('AC', 6)})}, 'GrenadeAreaExp': {frozenset({'Dash', ('AC', 6)})}, 'GrenadeAreaAbilityCell': {frozenset({'Grenade', 'Dash', ('AC', 6)})}, 'GumoHideoutRedirectPlant': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}, 'HollowGroveTreePlant': {frozenset({'Dash', ('AC', 6)})}, 'HollowGroveTreeAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'HollowGroveMapPlant': {frozenset({'Dash', ('AC', 6)})}, 'SwampTeleporterAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'HoruFieldsPlant': {frozenset({'Dash', ('AC', 6), ('EC', 3)})}, 'HoruFieldsEnergyCell': {frozenset({('EC', 2), 'Dash', ('AC', 6)})}, 'HoruFieldsHiddenExp': {frozenset({'Dash', ('AC', 6)})}, 'HoruLavaDrainedLeftExp': {frozenset({'Open', ('AC', 6), 'Dash'})}, 'HoruLavaDrainedRightExp': {frozenset({'Open', ('AC', 6), 'Dash'})}, 'HoruL4LowerExp': {frozenset({('EC', 2), 'Dash', ('AC', 6)}), frozenset({'Dash', 'Stomp', ('AC', 3)})}, 'HoruR3Plant': {frozenset({'Dash', ('AC', 6)})}, 'HoruR4DrainedExp': {frozenset({'Dash', ('AC', 6), ('EC', 1)}), frozenset({'Dash', ('AC', 6)})}, 'HoruR4LaserExp': {frozenset({('AC', 6), 'Dash', 'ChargeJump', ('EC', 2)})}, 'HoruL1': {frozenset({'Dash', 'Stomp', ('AC', 3), 'Bash'}), frozenset({('AC', 6), 'Dash', ('EC', 2), 'Stomp', 'DoubleJump'}), frozenset({('AC', 6), 'Dash', 'Stomp', ('EC', 3)})}, 'HoruL2': {frozenset({'Stomp', ('AC', 6), 'Dash', ('EC', 1)}), frozenset({'Climb', 'Stomp', 'Dash', ('AC', 3)})}, 'HoruL3': {frozenset({('AC', 6), 'Climb', 'Dash', ('EC', 2), 'ChargeJump'})}, 'LeftGumoHideoutUpperPlant': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}, 'LeftSorrowPlant': {frozenset({'Dash', ('AC', 6)})}, 'LowerBlackrootAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'LowerBlackrootLaserExp': {frozenset({'Dash', ('AC', 6)})}, 'LowerGinsoPlant': {frozenset({'Dash', ('AC', 6)})}, 'LeftGumoHideoutLowerPlant': {frozenset({'Dash', ('AC', 6)})}, 'LeftGumoHideoutHealthCell': {frozenset({'Dash', ('AC', 6)})}, 'SorrowSpikeKeystone': {frozenset({'Dash', ('AC', 6)})}, 'SorrowHiddenKeystone': {frozenset({'Dash', ('AC', 6)})}, 'SorrowLowerLeftKeystone': {frozenset({'Dash', ('AC', 6), 'Bash'}), frozenset({('EC', 2), 'Dash', ('AC', 6)}), frozenset({'Dash', ('AC', 6), 'DoubleJump'}), frozenset({('AC', 6), 'Dash', 'Stomp'})}, 'SpiritCavernsKeystone2': {frozenset({'Dash', ('AC', 6)})}, 'SpiritCavernsAbilityCell': {frozenset({'Dash', ('AC', 6)})}, 'LowerValleyMapstone': {frozenset({'Dash', ('AC', 6)})}, 'KuroPerchExp': {frozenset({'Dash', ('AC', 6), 'OpenWorld'}), frozenset({'Dash', ('AC', 3), 'ChargeJump', 'WallJump'}), frozenset({'Dash', ('AC', 6)})}, 'ValleyMainPlant': {frozenset({'Dash', ('AC', 6)})}, 'MistyEntranceTreeExp': {frozenset({'Dash', ('AC', 6)})}, 'MistyFrogNookExp': {frozenset({'Dash', ('AC', 6)})}, 'MistyMortarCorridorUpperExp': {frozenset({'Dash', ('AC', 6)})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Dash', ('AC', 6), 'DoubleJump'})}, 'MistyPlant': {frozenset({'Dash', ('AC', 6)})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'Dash', ('AC', 6)})}, 'AboveGrottoTeleporterExp': {frozenset({'Dash', ('AC', 6)})}, 'BelowGrottoTeleporterHealthCell': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}, 'BelowGrottoTeleporterPlant': {frozenset({'Dash', ('AC', 6)})}, 'MoonGrottoStompPlant': {frozenset({'Dash', ('AC', 6)})}, 'GrottoSwampDrainAccessExp': {frozenset({'Dash', ('AC', 6)})}, 'GrottoSwampDrainAccessPlant': {frozenset({'Dash', ('AC', 6)})}, 'OuterSwampStompExp': {frozenset({'Dash', ('AC', 6)})}, 'OuterSwampHealthCell': {frozenset({'Dash', ('AC', 6)})}, 'OuterSwampMortarPlant': {frozenset({'Dash', ('AC', 6)})}, 'RightForlornPlant': {frozenset({'Dash', ('AC', 6)})}, 'StompAreaExp': {frozenset({'Dash', ('AC', 6), ('EC', 1)})}, 'StompAreaGrenadeExp': {frozenset({('AC', 6), 'Dash', 'Water', 'Grenade', 'Stomp'}), frozenset({('AC', 6), 'Dash', ('EC', 3), 'Water', 'Grenade'})}, 'SorrowMapstone': {frozenset({'Dash', ('AC', 6)})}, 'AboveChargeFlameTreeExp': {frozenset({'Dash', ('AC', 6)})}, 'SpiderSacHealthCell': {frozenset({'Dash', ('AC', 6)})}, 'SpiderSacGrenadeDoor': {frozenset({'Grenade', 'Dash', ('AC', 6)})}, 'GroveAboveSpiderWaterExp': {frozenset({'Dash', ('AC', 6)})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Dash', ('AC', 6)})}, 'GroveAboveSpiderWaterEnergyCell': {frozenset({'Grenade', 'Dash', ('AC', 6)})}, 'GladesGrenadeTree': {frozenset({'Grenade', 'Dash', ('AC', 6)})}, 'FronkeyWalkRoof': {frozenset({'Dash', ('AC', 6)})}, 'SunstonePlant': {frozenset({'Dash', ('AC', 6)})}, 'InnerSwampDrainExp': {frozenset({'Climb', 'Dash', 'Water', 'Grenade', 'Stomp', ('AC', 3)}), frozenset({'Climb', 'Dash', ('AC', 6), 'Water'}), frozenset({'ChargeFlame', 'Climb', 'Dash', 'Water', 'Stomp', ('AC', 3)}), frozenset({'Dash', ('AC', 3), 'WallJump', 'Water'})}, 'SwampEntrancePlant': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}, 'InnerSwampStompExp': {frozenset({'Dash', 'ChargeJump', ('AC', 3), 'Water'})}, 'TopGinsoLeftLowerExp': {frozenset({'Dash', ('AC', 6)})}, 'TopGinsoLeftUpperExp': {frozenset({'Dash', ('AC', 6)})}, 'TopGinsoRightPlant': {frozenset({'Dash', ('AC', 6)})}, 'UpperGinsoRedirectLowerExp': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoRedirectUpperExp': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoLowerKeystone': {frozenset({('AC', 6), 'Dash', 'GinsoKey'})}, 'GrottoLasersRoofExp': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)})}, 'UpperSorrowLeftKeystone': {frozenset({('EC', 2), 'Dash', ('AC', 6)})}, 'ValleyThreeBirdAbilityCell': {frozenset({'Dash', ('AC', 6)}), frozenset({'Dash', ('AC', 6), 'OpenWorld'})}, 'ValleyEntryTreePlant': {frozenset({'Dash', ('AC', 6)})}, 'ValleyMap': {frozenset({'Grenade', 'Dash', 'MapStone', ('AC', 3)}), frozenset({'ChargeFlame', 'Dash', 'MapStone', ('AC', 3)})}, 'ValleyMainFACS': {frozenset({'WallJump', 'Dash', 'ChargeJump', 'DoubleJump', ('AC', 3)}), frozenset({'Wind', 'Dash', 'Glide', ('AC', 3), 'ChargeJump', 'WallJump'})}}, 'master-abilities': {'BashAreaExp': {frozenset({('AC', 12), 'GinsoKey', 'DoubleJump'})}, 'ForlornHiddenSpiderExp': {frozenset({'ForlornKey', ('AC', 12), 'DoubleJump'})}, 'ForlornKeystone2': {frozenset({'ForlornKey', ('AC', 12), 'DoubleJump'})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', ('AC', 12), 'DoubleJump'})}, 'GumoHideoutRedirectPlant': {frozenset({'Dash', ('AC', 6), 'DoubleJump'})}, 'SwampTeleporterAbilityCell': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump'})}, 'HoruFieldsAbilityCell': {frozenset({'Glide', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'HoruLavaDrainedLeftExp': {frozenset({'Open', ('AC', 12), 'DoubleJump'})}, 'HoruLavaDrainedRightExp': {frozenset({'Open', 'ChargeJump', 'DoubleJump', ('AC', 12)}), frozenset({'Glide', 'Open', ('AC', 12), 'DoubleJump'})}, 'HoruR4DrainedExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'HoruL1': {frozenset({('AC', 6), ('EC', 1), 'Dash', 'Stomp', 'DoubleJump'})}, 'HoruL2': {frozenset({'Stomp', 'DoubleJump', ('AC', 3), 'Dash'}), frozenset({'Stomp', ('AC', 12), 'DoubleJump'})}, 'HoruL3': {frozenset({('AC', 6), 'Dash', ('EC', 6), 'DoubleJump', 'WallJump'}), frozenset({('AC', 6), 'Dash', ('EC', 2), 'Stomp', 'DoubleJump'}), frozenset({('AC', 6), 'Dash', 'Stomp', ('EC', 3)}), frozenset({('AC', 6), ('EC', 4), 'Dash', 'Glide', 'DoubleJump'}), frozenset({'Dash', ('AC', 6), ('EC', 7)}), frozenset({'Glide', 'Dash', ('AC', 6), ('EC', 6)}), frozenset({('AC', 12), 'Climb', 'Dash', 'Glide', 'ChargeJump', 'DoubleJump'}), frozenset({'Bash', ('AC', 6), 'Dash', ('EC', 1)}), frozenset({('AC', 6), 'Climb', 'Dash', ('EC', 6), 'DoubleJump'})}, 'LeftSorrowAbilityCell': {frozenset({'Climb', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'LowerGinsoHiddenExp': {frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({'Dash', ('AC', 6), 'WallJump'})}, 'LeftGumoHideoutExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'LeftGumoHideoutHealthCell': {frozenset({('AC', 12), 'DoubleJump'})}, 'SorrowSpikeKeystone': {frozenset({'Climb', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'SorrowLowerLeftKeystone': {frozenset({('AC', 12), 'DoubleJump'})}, 'SpiritCavernsAbilityCell': {frozenset({('AC', 12), 'DoubleJump'})}, 'MistyFrogNookExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'MistyMortarCorridorUpperExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'MistyMortarCorridorHiddenExp': {frozenset({('AC', 12), 'DoubleJump'}), frozenset({'Dash', ('AC', 6)})}, 'BelowGrottoTeleporterHealthCell': {frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'OuterSwampHealthCell': {frozenset({('AC', 12), 'DoubleJump'})}, 'SpiderSacHealthCell': {frozenset({'Dash', ('AC', 6), 'DoubleJump'})}, 'TopGinsoLeftUpperExp': {frozenset({('AC', 12), 'DoubleJump'})}, 'TopGinsoRightPlant': {frozenset({'ChargeFlame', ('AC', 12), 'DoubleJump'}), frozenset({'Grenade', ('AC', 12), 'DoubleJump'})}, 'UpperSorrowRightKeystone': {frozenset({('AC', 6), 'Dash', 'Grenade', 'Bash', 'DoubleJump'})}, 'UpperSorrowFarRightKeystone': {frozenset({('AC', 12), 'Dash', 'Grenade', 'Bash', 'DoubleJump'})}, 'ValleyThreeBirdAbilityCell': {frozenset({('AC', 12), 'DoubleJump'})}, 'WilhelmExp': {frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'KuroPerchExp': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'master-core': {'DashAreaRoofExp': {frozenset({'DoubleJump'}), frozenset({'Bash'})}, 'DoubleJumpAreaExp': {frozenset({'DoubleJump'})}, 'ForlornKeystone4': {frozenset({'Grenade', 'ForlornKey', 'DoubleJump', 'Bash'}), frozenset({'ForlornKey', 'ChargeJump', 'DoubleJump'})}, 'LowerGinsoKeystone3': {frozenset({'DoubleJump'})}, 'LowerGinsoKeystone4': {frozenset({'DoubleJump'})}, 'GladesLaserGrenade': {frozenset({'Grenade', 'Bash', 'DoubleJump'})}, 'GrenadeSkillTree': {frozenset({'ChargeJump'})}, 'GrenadeAreaAbilityCell': {frozenset({'Grenade', 'ChargeJump'})}, 'GumoHideoutMiniboss': {frozenset({'DoubleJump'})}, 'GumoHideoutEnergyCell': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'}), frozenset({'DoubleJump'})}, 'HollowGroveTreeAbilityCell': {frozenset({'Stomp', 'DoubleJump'})}, 'SwampTeleporterAbilityCell': {frozenset({'Glide', 'ChargeJump', 'DoubleJump'})}, 'DoorWarpExp': {frozenset({'DoubleJump'})}, 'HoruFieldsPlant': {frozenset({'Grenade', 'Glide'}), frozenset({'Grenade', 'Dash'}), frozenset({'Grenade', 'DoubleJump'})}, 'HoruFieldsAbilityCell': {frozenset({'Bash'})}, 'HoruL4LowerExp': {frozenset({'Dash', 'Stomp'})}, 'HoruR1EnergyCell': {frozenset({'DoubleJump'})}, 'HoruL2': {frozenset({'Glide', 'Stomp', 'DoubleJump'})}, 'HoruL3': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'Bash', 'Stomp'})}, 'WallJumpAreaEnergyCell': {frozenset({'DoubleJump'})}, 'FarLeftGumoHideoutExp': {frozenset({'Bash'})}, 'LeftSorrowAbilityCell': {frozenset({'Bash'})}, 'LeftSorrowKeystone2': {frozenset({'Bash'})}, 'LeftSorrowKeystone3': {frozenset({'Bash'})}, 'LeftSorrowKeystone4': {frozenset({'Bash'})}, 'LeftSorrowEnergyCell': {frozenset({'Bash'})}, 'LowerBlackrootAbilityCell': {frozenset({'DoubleJump'})}, 'LowerGinsoHiddenExp': {frozenset({'DoubleJump'})}, 'SorrowSpikeKeystone': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump'})}, 'SorrowLowerLeftKeystone': {frozenset({'Bash'})}, 'SpiritCavernsKeystone2': {frozenset({'Free'})}, 'LowerValleyMapstone': {frozenset({'Free'})}, 'MistyEntranceStompExp': {frozenset({('EC', 2), 'Dash', ('AC', 6)}), frozenset({'ChargeFlame', 'Dash'})}, 'MistyEntranceTreeExp': {frozenset({'DoubleJump'}), frozenset({'WallJump'})}, 'MistyPostClimbAboveSpikePit': {frozenset({'Bash'})}, 'MistyMortarCorridorUpperExp': {frozenset({'Bash'})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Bash'})}, 'OuterSwampHealthCell': {frozenset({'Glide', 'DoubleJump'}), frozenset({'Bash'})}, 'OutsideForlornTreeExp': {frozenset({'Bash'})}, 'HoruR1HangingExp': {frozenset({'Glide', 'WallJump'})}, 'HoruR2': {frozenset({'Stomp', 'DoubleJump'})}, 'HoruR4DrainedExp': {frozenset({'Bash'})}, 'StompAreaExp': {frozenset({'Grenade'})}, 'AboveChargeFlameTreeExp': {frozenset({'Glide', 'Bash', 'DoubleJump'}), frozenset({'Stomp', 'DoubleJump'}), frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'Grenade', 'DoubleJump'})}, 'SpiderSacHealthCell': {frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'Grenade', 'DoubleJump'})}, 'SpiderSacEnergyDoor': {frozenset({('EC', 2)})}, 'InnerSwampDrainExp': {frozenset({'DoubleJump', 'Water'})}, 'TopGinsoLeftLowerExp': {frozenset({'DoubleJump'})}, 'UpperGinsoRedirectLowerExp': {frozenset({'Grenade', 'GinsoKey'})}, 'GrottoLasersRoofExp': {frozenset({'Glide', 'DoubleJump'}), frozenset({'Bash'})}, 'SpiritCavernsTopLeftKeystone': {frozenset({'DoubleJump'}), frozenset({'Climb'})}, 'KuroPerchExp': {frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Bash'}), frozenset({'Glide', 'ChargeJump'})}}, 'glitched': {'BlackrootBoulderExp': {frozenset({'Free'})}, 'GroveWaterStompAbilityCell': {frozenset({'Bash'})}, 'SpiderSacEnergyDoor': {frozenset({('EC', 3)})}, 'GladesGrenadeTree': {frozenset({'Grenade'})}, 'KuroPerchExp': {frozenset({'ChargeJump'})}}, 'standard-abilities': {'BlackrootMap': {frozenset({'Climb', 'Dash', 'MapStone', ('AC', 3)})}, 'DoubleJumpSkillTree': {frozenset({'Dash', ('AC', 3)})}, 'DoubleJumpAreaExp': {frozenset({'Dash', 'ChargeJump', ('AC', 3)}), frozenset({'Bash', 'Dash', ('AC', 3)})}, 'ForlornKeystone3': {frozenset({'ForlornKey', 'ChargeJump', 'Dash', ('AC', 3)})}, 'LowerGinsoKeystone1': {frozenset({'Dash', ('AC', 3)})}, 'LowerGinsoKeystone2': {frozenset({'Dash', ('AC', 3)})}, 'GladesLaserGrenade': {frozenset({'Dash', 'Grenade', 'Glide', ('AC', 3), 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Dash', 'Grenade', 'ChargeJump', 'DoubleJump', ('AC', 3)})}, 'GumoHideoutMapstone': {frozenset({'Dash', ('AC', 3)})}, 'GumoHideoutRedirectAbilityCell': {frozenset({'Dash', ('AC', 3)})}, 'HollowGroveTreeAbilityCell': {frozenset({'WallJump', 'Dash', 'Glide', 'Stomp', ('AC', 3)}), frozenset({'Climb', 'Dash', 'Glide', 'Stomp', ('AC', 3)})}, 'SwampTeleporterAbilityCell': {frozenset({'Dash', 'Glide', 'ChargeJump', 'DoubleJump', ('AC', 3)})}, 'HoruFieldsPlant': {frozenset({'Dash', 'Grenade', 'ChargeJump', 'DoubleJump', ('AC', 3)}), frozenset({'ChargeFlame', 'Dash', 'ChargeJump', 'DoubleJump', ('AC', 3)})}, 'HoruFieldsEnergyCell': {frozenset({'Dash', 'ChargeJump', 'DoubleJump', ('AC', 3)}), frozenset({'Glide', 'ChargeJump', 'Dash', ('AC', 3)})}, 'HoruLavaDrainedLeftExp': {frozenset({'Glide', 'Open', 'Dash', ('AC', 3)})}, 'HoruR1EnergyCell': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}, 'HoruR4DrainedExp': {frozenset({'Dash', 'DoubleJump', ('AC', 3)}), frozenset({'Glide', 'Dash', ('AC', 3)})}, 'InnerSwampDrainExp': {frozenset({'Dash', ('AC', 3)})}, 'HoruL1': {frozenset({'WallJump', 'Dash', 'Stomp', ('AC', 3), 'Bash'}), frozenset({'Dash', 'Grenade', 'Stomp', ('AC', 3), 'Bash'}), frozenset({'Dash', 'Stomp', 'ChargeJump', ('AC', 3), 'Bash'}), frozenset({'Climb', 'Dash', 'Stomp', ('AC', 3), 'Bash'})}, 'HoruL2': {frozenset({'Stomp', ('AC', 3), 'Dash', 'WallJump'}), frozenset({'Climb', 'Dash', 'Stomp', 'DoubleJump', ('AC', 3)})}, 'HoruL3': {frozenset({'Bash', 'Stomp', 'Dash', ('AC', 3)}), frozenset({'ChargeFlame', 'Bash', 'Dash', ('AC', 3)})}, 'FarLeftGumoHideoutExp': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}, 'GumoHideoutLeftHangingExp': {frozenset({'Dash', ('AC', 3)})}, 'MistyFrogNookExp': {frozenset({'Dash', ('AC', 3), 'DoubleJump', 'WallJump'})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'Climb', 'Dash', ('AC', 3)})}, 'BelowGrottoTeleporterPlant': {frozenset({'Grenade', 'Dash', ('AC', 3)}), frozenset({'ChargeFlame', 'Dash', ('AC', 3)})}, 'GrottoSwampDrainAccessPlant': {frozenset({'ChargeFlame', 'Dash', ('AC', 3), 'WallJump'}), frozenset({'ChargeFlame', 'Glide', 'Dash', ('AC', 3)})}, 'HoruR1HangingExp': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}, 'HoruLavaDrainedRightExp': {frozenset({'Dash', ('AC', 3)})}, 'AboveChargeFlameTreeExp': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}, 'UpperGinsoLowerKeystone': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoRightKeystone': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoUpperLeftKeystone': {frozenset({'Dash', ('AC', 3), 'GinsoKey', 'ChargeJump'})}}, 'expert-core': {'BlackrootMap': {frozenset({'Climb', 'MapStone'})}, 'DashAreaMapstone': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'DoubleJumpSkillTree': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'})}, 'DoubleJumpAreaExp': {frozenset({'Climb', 'Bash', 'Water'}), frozenset({'Grenade', 'Bash'})}, 'ForlornHiddenSpiderExp': {frozenset({'ForlornKey', 'DoubleJump', 'WallJump'})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', 'Open'})}, 'GladesLaserGrenade': {frozenset({'Water', 'Grenade', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump', 'Water'})}, 'GrenadeSkillTree': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Dash', 'Bash'})}, 'GumoHideoutCrusherExp': {frozenset({'DoubleJump'})}, 'GumoHideoutCrusherKeystone': {frozenset({'DoubleJump'})}, 'SwampTeleporterAbilityCell': {frozenset({'Grenade', 'Bash'})}, 'HoruL4LowerExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'})}, 'HoruR1EnergyCell': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Climb', 'Glide'})}, 'HoruR4DrainedExp': {frozenset({'Glide', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'HoruL1': {frozenset({'Glide', 'Stomp', 'Bash'})}, 'HoruL2': {frozenset({'Climb', 'Stomp', 'Glide', 'DoubleJump'})}, 'HoruL3': {frozenset({'Grenade', 'Bash', 'ChargeJump'})}, 'LeftGumoHideoutUpperPlant': {frozenset({'ChargeFlame'})}, 'LeftSorrowKeystone1': {frozenset({'ChargeJump', 'WallJump'})}, 'LeftSorrowKeystone2': {frozenset({'ChargeJump', 'WallJump'})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Glide', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'LowerBlackrootLaserExp': {frozenset({'Grenade', 'Bash'}), frozenset({'DoubleJump'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'GumoHideoutRightHangingExp': {frozenset({'DoubleJump'})}, 'LeftGumoHideoutExp': {frozenset({'Climb', 'DoubleJump'})}, 'SorrowHiddenKeystone': {frozenset({'Bash', 'ChargeJump', 'WallJump'})}, 'SorrowHealthCell': {frozenset({'Climb', 'ChargeJump'})}, 'SorrowLowerLeftKeystone': {frozenset({'Bash', 'DoubleJump'})}, 'SpiritCavernsAbilityCell': {frozenset({'Climb', 'DoubleJump'})}, 'KuroPerchExp': {frozenset({'Glide', 'ChargeJump', 'WallJump'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'})}, 'MistyEntranceStompExp': {frozenset({'Climb', 'Dash', 'ChargeJump'})}, 'MistyEntranceTreeExp': {frozenset({'Bash'})}, 'MistyPostClimbAboveSpikePit': {frozenset({'Bash', 'DoubleJump'})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Bash', 'DoubleJump'})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'Climb', 'Glide'})}, 'LeftGrottoTeleporterExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'HoruR1HangingExp': {frozenset({'DoubleJump'}), frozenset({'Dash'})}, 'HoruR2': {frozenset({'Stomp', 'WallJump'}), frozenset({'Grenade', 'Stomp', 'Bash'}), frozenset({'Climb', 'Stomp'}), frozenset({'Stomp', 'ChargeJump'})}, 'StompAreaExp': {frozenset({'ChargeFlame'})}, 'AboveChargeFlameTreeExp': {frozenset({'ChargeFlame', 'Climb', 'Glide'}), frozenset({'Dash', 'WallJump'}), frozenset({'Grenade', 'Climb', 'Glide'}), frozenset({'ChargeFlame', 'Glide', 'WallJump'}), frozenset({'Grenade', 'Glide', 'WallJump'}), frozenset({'Climb', 'Stomp', 'Glide'}), frozenset({'Glide', 'Stomp', 'WallJump'}), frozenset({'Climb', 'Dash'})}, 'SpiderSacGrenadeDoor': {frozenset({'Grenade', 'Climb', 'DoubleJump'})}, 'InnerSwampDrainExp': {frozenset({'ChargeJump', 'DoubleJump', 'Water'}), frozenset({'Glide', 'Dash', 'WallJump', 'Water'})}, 'SwampEntrancePlant': {frozenset({'Grenade'})}, 'InnerSwampStompExp': {frozenset({'Grenade', 'Bash', 'ChargeJump', 'Water'})}, 'InnerSwampSwimRightKeystone': {frozenset({'DoubleJump'})}, 'UpperGinsoRedirectLowerExp': {frozenset({'ChargeFlame', 'GinsoKey'})}, 'UpperGinsoRedirectUpperExp': {frozenset({'Climb', 'GinsoKey', 'ChargeJump'}), frozenset({'ChargeFlame', 'GinsoKey'})}, 'UpperGinsoEnergyCell': {frozenset({'Dash', 'GinsoKey', 'ChargeJump'}), frozenset({'ChargeFlame', 'GinsoKey'})}, 'LeftGladesExp': {frozenset({'DoubleJump'}), frozenset({'Bash'})}, 'UpperSorrowLeftKeystone': {frozenset({'Grenade', 'Bash'})}, 'ValleyMap': {frozenset({'Grenade', 'MapStone', 'DoubleJump'}), frozenset({'Grenade', 'MapStone', 'ChargeJump'}), frozenset({'ChargeFlame', 'MapStone', 'ChargeJump'}), frozenset({'ChargeFlame', 'MapStone', 'DoubleJump'})}, 'WilhelmExp': {frozenset({'Climb', 'Bash'}), frozenset({'Grenade', 'Bash'})}}, 'expert-dboost': {'UpperSorrowSpikeExp': {frozenset({('AC', 6), 'Dash', 'ChargeJump', ('HC', 2)}), frozenset({('EC', 2), 'Dash', ('AC', 6), ('HC', 2)}), frozenset({'Grenade', 'Bash', 'DoubleJump', ('HC', 2)}), frozenset({('AC', 6), 'Dash', ('HC', 2), 'Grenade', 'Bash'})}, 'DeathGauntletStompSwim': {frozenset({('HC', 0)})}, 'DoubleJumpAreaExp': {frozenset({'Climb', 'Bash', ('HC', -1)})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', 'WallJump', ('HC', 1)})}, 'GladesLaser': {frozenset({'Glide', 'WallJump'})}, 'GladesLaserGrenade': {frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Climb', 'Dash', 'Grenade', 'Glide'}), frozenset({'Grenade', 'Glide', 'ChargeJump', ('HC', 0)}), frozenset({('AC', 6), ('EC', 1), 'Climb', 'Dash', ('HC', 2), 'Grenade'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Climb', 'Dash', 'Grenade', 'DoubleJump'}), frozenset({('HC', 0), 'Grenade', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Grenade', 'ChargeJump'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Climb', 'Dash', 'Water', 'Grenade'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Dash', 'Grenade', 'Glide', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump', ('HC', 0)}), frozenset({'Grenade', 'ChargeJump', ('HC', 2)}), frozenset({('HC', 0), ('EC', 2), 'Grenade', 'ChargeJump', ('AC', 3)}), frozenset({('AC', 6), ('HC', 0), ('EC', 2), 'Dash', 'Grenade', 'WallJump'}), frozenset({('AC', 6), ('HC', 0), ('EC', 1), 'Dash', 'Water', 'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash', 'ChargeJump', ('HC', 0)}), frozenset({'Grenade', 'ChargeJump', ('HC', 0), 'Water'}), frozenset({('AC', 6), ('HC', 0), ('EC', 2), 'Climb', 'Dash', 'Grenade'}), frozenset({('EC', 1), ('HC', 1), 'Grenade', 'ChargeJump', ('AC', 3)}), frozenset({('AC', 6), ('EC', 1), 'Dash', ('HC', 2), 'Grenade', 'WallJump'})}, 'GroveWaterStompAbilityCell': {frozenset({'Stomp', ('HC', 2)}), frozenset({('HC', 3), 'Bash'})}, 'HoruFieldsAbilityCell': {frozenset({'Bash', 'WallJump', ('HC', 2)})}, 'HoruR1EnergyCell': {frozenset({'WallJump', ('HC', 2)}), frozenset({'Climb', ('HC', 2)})}, 'HoruR4DrainedExp': {frozenset({('HC', 3), 'DoubleJump'}), frozenset({('HC', 3), 'Dash', ('AC', 3)}), frozenset({('HC', 3), 'Glide'})}, 'LeftSorrowAbilityCell': {frozenset({'Climb', 'ChargeJump', ('HC', 2)}), frozenset({'ChargeJump', 'WallJump', ('HC', 2)})}, 'LeftSorrowKeystone3': {frozenset({'Climb', 'ChargeJump', ('HC', 2)})}, 'LeftSorrowKeystone4': {frozenset({'Climb', 'ChargeJump', 'DoubleJump', ('HC', 2)}), frozenset({'Climb', 'Dash', 'ChargeJump', ('HC', 2)})}, 'LeftSorrowEnergyCell': {frozenset({'Climb', 'ChargeJump', 'DoubleJump', ('HC', 2)})}, 'LowerBlackrootAbilityCell': {frozenset({'DoubleJump', ('HC', 2)})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'DoubleJump', ('HC', 1)}), frozenset({'ChargeJump', ('HC', 1)}), frozenset({'Glide', 'Stomp', ('HC', 1)}), frozenset({'Glide', 'WallJump', ('HC', 1)}), frozenset({'Dash', ('AC', 3), ('HC', 1)})}, 'LeftGumoHideoutSwim': {frozenset({'Free'})}, 'SorrowSpikeKeystone': {frozenset({'Climb', 'DoubleJump', ('HC', 2)}), frozenset({'ChargeJump', 'WallJump', ('HC', 2)}), frozenset({'Climb', 'ChargeJump', ('HC', 2)}), frozenset({'DoubleJump', 'WallJump', ('HC', 2)})}, 'SorrowHiddenKeystone': {frozenset({'Climb', 'Bash', ('HC', 2)}), frozenset({'Bash', 'WallJump', ('HC', 2)})}, 'SorrowHealthCell': {frozenset({'ChargeJump', 'DoubleJump', 'WallJump', ('HC', 2)})}, 'MistyFrogNookExp': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({('HC', 4), 'Dash', 'WallJump'})}, 'MistyPostClimbSpikeCave': {frozenset({'Glide', ('HC', 1)})}, 'MistyMortarCorridorUpperExp': {frozenset({'ChargeJump', ('HC', 1)}), frozenset({'Bash', ('HC', 1)})}, 'MistyMortarCorridorHiddenExp': {frozenset({'Grenade', 'Bash', ('HC', 1)}), frozenset({'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({'Dash', ('AC', 3), ('HC', 1)}), frozenset({('HC', 4), 'Bash'})}, 'GrottoEnergyDoorSwim': {frozenset({('EC', 2)})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'Climb', 'DoubleJump'})}, 'LeftGrottoTeleporterExp': {frozenset({('HC', 4), 'WallJump'}), frozenset({'Glide', 'DoubleJump', ('HC', 1)}), frozenset({'Climb', 'Glide', ('HC', 1)}), frozenset({'ChargeJump', ('HC', 1)}), frozenset({'Climb', ('HC', 4)}), frozenset({'Glide', 'WallJump', ('HC', 1)})}, 'BelowGrottoTeleporterHealthCell': {frozenset({'Bash', ('HC', 2)})}, 'OutsideForlornWaterExp': {frozenset({('HC', 1)}), frozenset({'Stomp', ('HC', -1)})}, 'HoruR1HangingExp': {frozenset({'ChargeJump', ('HC', 2)})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', ('HC', 0)}), frozenset({('HC', 0), 'Climb', 'Dash', 'Water', 'Grenade', 'Stomp', 'DoubleJump', ('AC', 3)}), frozenset({'Climb', 'Dash', ('HC', 1), 'Grenade', 'Stomp', 'DoubleJump', ('AC', 3)}), frozenset({('HC', 0), 'Water', 'Grenade', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({('AC', 6), 'Dash', ('EC', 3), 'Grenade', ('HC', 1)}), frozenset({('HC', 1), 'Grenade', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'ChargeJump', ('HC', 1)})}, 'GroveSpiderWaterSwim': {frozenset({'Bash', ('HC', 2)}), frozenset({('HC', 3)})}, 'GladesGrenadePool': {frozenset({'Grenade', ('HC', 3)}), frozenset({'Grenade', 'Stomp', ('HC', 2)})}, 'GladesMainPool': {frozenset({'Bash', ('HC', 0)}), frozenset({('HC', 1)}), frozenset({'Stomp', ('HC', 0)})}, 'GladesMainPoolDeep': {frozenset({('HC', 4)})}, 'SwampEntranceSwim': {frozenset({'Free'})}, 'InnerSwampStompExp': {frozenset({'Dash', 'ChargeJump', ('AC', 3)}), frozenset({'Stomp'}), frozenset({'Grenade', 'Bash', 'ChargeJump'})}, 'TopGinsoLeftLowerExp': {frozenset({('HC', 2)})}, 'TopGinsoRightPlant': {frozenset({'ChargeFlame', 'DoubleJump', 'WallJump', ('HC', 0)}), frozenset({'Climb', ('HC', 0), 'DoubleJump', 'ChargeFlame'})}, 'UpperGinsoLowerKeystone': {frozenset({'GinsoKey', ('HC', 2)})}, 'UpperGinsoRightKeystone': {frozenset({'GinsoKey', 'DoubleJump', 'WallJump', ('HC', 2)})}, 'UpperSorrowRightKeystone': {frozenset({('AC', 6), 'Dash', 'ChargeJump', ('HC', 2)})}, 'UpperSorrowLeftKeystone': {frozenset({'ChargeJump', ('HC', 2)})}, 'ValleyRightSwimExp': {frozenset({('HC', 1)})}, 'ValleyRightFastStomplessCell': {frozenset({'ChargeJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', 'ChargeJump', ('HC', 1)}), frozenset({'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'ValleyRightExp': {frozenset({'ChargeJump', 'DoubleJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'ValleyMainFACS': {frozenset({'WallJump', 'Dash', ('HC', 1), 'ChargeJump', ('AC', 3)})}, 'WilhelmExp': {frozenset({'ChargeJump', ('HC', 2)})}}, 'master-lure': {'UpperSorrowSpikeExp': {frozenset({'Bash'})}, 'UpperSorrowFarLeftKeystone': {frozenset({'Bash'})}, 'UpperSorrowRightKeystone': {frozenset({'Bash'})}, 'UpperSorrowFarRightKeystone': {frozenset({'Bash'})}, 'UpperSorrowLeftKeystone': {frozenset({'Bash'})}, 'ForlornKeystone2': {frozenset({'ForlornKey', 'Bash'})}, 'ForlornEscape': {frozenset({'Bash'})}, 'ForlornKeystone3': {frozenset({'ForlornKey', 'Bash'})}, 'GroveWaterStompAbilityCell': {frozenset({('AC', 12)}), frozenset({('HC', 2)})}, 'SwampTeleporterAbilityCell': {frozenset({'Bash'})}, 'WallJumpAreaExp': {frozenset({'Bash'})}, 'WallJumpAreaEnergyCell': {frozenset({'Bash'})}, 'SorrowHealthCell': {frozenset({'Glide', 'Stomp', 'WallJump'}), frozenset({'Glide', 'Stomp', 'DoubleJump'}), frozenset({'Climb', 'Glide', 'Stomp'})}, 'KuroPerchExp': {frozenset({'Bash'})}, 'LeftGrottoTeleporterExp': {frozenset({'Bash'})}, 'InnerSwampDrainExp': {frozenset({'Bash', 'Water'})}, 'InnerSwampStompExp': {frozenset({'Bash', 'Water'}), frozenset({'Bash', ('HC', 0)})}}, 'master-dboost': {'UpperSorrowSpikeExp': {frozenset({('AC', 12), 'Dash', 'Grenade', 'Bash', ('HC', 1)}), frozenset({('AC', 12), 'Grenade', 'Bash', 'DoubleJump', ('HC', 1)}), frozenset({('EC', 2), 'Dash', ('AC', 12), ('HC', 1)}), frozenset({('AC', 12), 'Dash', 'ChargeJump', ('HC', 1)}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'UpperSorrowFarLeftKeystone': {frozenset({('AC', 12), 'Dash', ('HC', 1), 'Grenade', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({('AC', 12), 'Dash', ('HC', 1), 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({('HC', 4), ('AC', 12), 'Climb', 'Grenade', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({('AC', 12), 'Climb', 'Dash', 'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 12), 'Climb', 'ChargeJump', 'DoubleJump', ('HC', 7)}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', 'WallJump', ('HC', 7)}), frozenset({('AC', 12), 'Climb', 'Dash', 'Grenade', 'Bash', 'DoubleJump', ('HC', 1)}), frozenset({('HC', 4), ('AC', 12), 'Grenade', 'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', ('AC', 12), ('HC', 0), 'WallJump'})}, 'HoruR1EnergyCell': {frozenset({('AC', 12), 'WallJump', ('HC', 1)}), frozenset({'Climb', ('AC', 12), ('HC', 1)})}, 'HoruR4DrainedExp': {frozenset({('HC', 8)}), frozenset({('AC', 12), ('HC', 6)})}, 'HoruL1': {frozenset({('EC', 1), ('AC', 12), 'Climb', ('HC', 2), 'Stomp', 'DoubleJump'}), frozenset({('AC', 12), 'Climb', ('EC', 2), 'Stomp', 'DoubleJump', ('HC', 1)}), frozenset({('HC', 4), ('AC', 12), 'Climb', 'Stomp', 'DoubleJump'}), frozenset({('AC', 12), ('HC', 1), 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Bash', 'Stomp', ('HC', 2)}), frozenset({'Stomp', 'ChargeJump', ('HC', 2)})}, 'HoruL3': {frozenset({('HC', 3), ('AC', 12), 'Climb', 'Dash', ('EC', 2), 'Glide', 'DoubleJump'}), frozenset({('HC', 0), ('AC', 12), 'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'ChargeFlame', ('HC', 0), ('AC', 12), 'ChargeJump', 'DoubleJump'}), frozenset({('EC', 1), ('AC', 12), 'Climb', 'Dash', 'Glide', 'Stomp', 'DoubleJump', ('HC', 1)}), frozenset({'Climb', 'Glide', 'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({('HC', 0), ('AC', 12), 'Stomp', 'ChargeJump', 'DoubleJump'})}, 'LeftSorrowAbilityCell': {frozenset({('AC', 12), 'ChargeJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', ('AC', 12), 'ChargeJump', ('HC', 1)})}, 'LeftSorrowKeystone3': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'LeftSorrowKeystone4': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'LeftSorrowEnergyCell': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 1)})}, 'LostGroveLongSwim': {frozenset({('HC', 3), ('AC', 12)}), frozenset({('HC', 9)})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Stomp', ('HC', 1)})}, 'SorrowLowerLeftKeystone': {frozenset({('AC', 12), 'ChargeJump', ('HC', 7)})}, 'MistyFrogNookExp': {frozenset({'DoubleJump', ('HC', 1)})}, 'MistyPostClimbSpikeCave': {frozenset({'Bash', ('HC', 1)}), frozenset({'DoubleJump', ('HC', 8)})}, 'MistyMortarCorridorHiddenExp': {frozenset({('HC', 7)}), frozenset({('HC', 4), ('AC', 12)}), frozenset({'DoubleJump', ('HC', 1)})}, 'LeftGrottoTeleporterExp': {frozenset({'DoubleJump', ('HC', 1)})}, 'OutsideForlornWaterExp': {frozenset({('AC', 12), ('HC', -1)})}, 'HoruR1HangingExp': {frozenset({('AC', 12), 'ChargeJump', ('HC', 1)})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'DoubleJump', ('HC', 2)}), frozenset({'Water', ('HC', 2), 'Grenade', 'Stomp', 'DoubleJump'}), frozenset({'Grenade', 'Stomp', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 12), 'Water', ('HC', 2), 'Grenade', 'DoubleJump'})}, 'GroveSpiderWaterSwim': {frozenset({('HC', 2)}), frozenset({'Bash', ('AC', 12)}), frozenset({('AC', 12), ('HC', 1)})}, 'GladesGrenadePool': {frozenset({'Grenade', ('HC', 2)})}, 'GladesMainPool': {frozenset({('HC', 0)})}, 'InnerSwampDrainExp': {frozenset({('HC', 4), 'Dash', ('AC', 12), 'WallJump'}), frozenset({('HC', 4), 'Bash', ('AC', 12)}), frozenset({('HC', 4), ('AC', 12), 'Grenade', 'Glide', 'Stomp', 'WallJump'}), frozenset({'Climb', ('HC', 4), 'ChargeJump', ('AC', 12)}), frozenset({'ChargeFlame', ('HC', 4), ('AC', 12), 'Glide', 'Stomp', 'WallJump'}), frozenset({('HC', 4), ('AC', 12), 'DoubleJump'}), frozenset({'Climb', 'Dash', ('HC', 4), ('AC', 12)})}, 'TopGinsoLeftUpperExp': {frozenset({('HC', 0), 'Glide', 'DoubleJump'}), frozenset({('HC', 0), 'Dash', 'DoubleJump'})}, 'TopGinsoRightPlant': {frozenset({'ChargeFlame', 'DoubleJump', ('HC', 0)}), frozenset({'Grenade', 'DoubleJump', ('HC', 0)})}, 'UpperGinsoRightKeystone': {frozenset({('HC', 0), ('AC', 12), 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoUpperRightKeystone': {frozenset({('AC', 12), 'GinsoKey', 'DoubleJump', ('HC', 2)})}, 'UpperGinsoUpperLeftKeystone': {frozenset({('AC', 12), 'GinsoKey', 'DoubleJump', ('HC', 2)})}, 'UpperSorrowRightKeystone': {frozenset({('HC', 4), 'ChargeJump', 'DoubleJump', ('AC', 12)}), frozenset({('AC', 12), 'Grenade', 'Bash', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 12), 'Dash', 'ChargeJump', ('HC', 1)}), frozenset({('AC', 12), 'ChargeJump', ('HC', 7)})}, 'UpperSorrowFarRightKeystone': {frozenset({('HC', 4), 'Dash', 'ChargeJump', ('AC', 12)}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 7)}), frozenset({('HC', 4), ('AC', 12), 'Grenade', 'Bash', 'DoubleJump'})}, 'UpperSorrowLeftKeystone': {frozenset({('AC', 12), 'ChargeJump', ('HC', 1)})}, 'ValleyEntryGrenadeLongSwim': {frozenset({'Grenade', 'Bash', ('HC', 10)}), frozenset({'Grenade', ('HC', 11)}), frozenset({'Grenade', ('HC', 4), ('AC', 12)})}, 'ValleyRightFastStomplessCell': {frozenset({'Climb', ('HC', 4), ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump', ('HC', 2)})}, 'ValleyRightExp': {frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'WilhelmExp': {frozenset({('AC', 12), 'ChargeJump', ('HC', 1)})}}, 'standard-lure': {'DeathGauntletExp': {frozenset({'Bash'})}, 'DeathGauntletStompSwim': {frozenset({'Water'})}, 'GladesLaser': {frozenset({'Bash'})}, 'HoruFieldsHealthCell': {frozenset({'Free'})}, 'HollowGroveTreeAbilityCell': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}, 'HoruL2': {frozenset({'Stomp', 'DoubleJump', 'Bash'})}, 'LeftSorrowKeystone1': {frozenset({'Bash'})}, 'MistyEntranceStompExp': {frozenset({'Bash'})}, 'MistyAbilityCell': {frozenset({'Bash'})}, 'GrottoSwampDrainAccessPlant': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'Grenade'})}, 'SorrowMap': {frozenset({'MapStone'})}, 'FronkeyWalkRoof': {frozenset({'Bash'})}, 'ValleyRightFastStomplessCell': {frozenset({'Bash'})}, 'WilhelmExp': {frozenset({'Bash', 'WallJump'})}, 'KuroPerchExp': {frozenset({'HoruKey'})}}, 'casual-dboost': {'DoubleJumpSkillTree': {frozenset({'Bash', ('HC', 0)}), frozenset({'Climb', ('HC', 0)}), frozenset({'ChargeJump', ('HC', 0)})}, 'DoubleJumpAreaExp': {frozenset({'Grenade', 'Bash', ('HC', 0)}), frozenset({'ChargeJump', ('HC', 0), 'Water'}), frozenset({('HC', -1), 'ChargeJump', 'WallJump'}), frozenset({'Bash', ('HC', 0), 'Water'}), frozenset({'Bash', 'WallJump', ('HC', -1)})}, 'GrenadeAreaExp': {frozenset({'ChargeJump'})}, 'GumoHideoutCrusherKeystone': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'GumoHideoutRedirectAbilityCell': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'WallJump'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'ChargeJump', 'Water'})}, 'SpiderSacHealthCell': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'InnerSwampSwimRightKeystone': {frozenset({'Climb'}), frozenset({'WallJump'})}, 'SpiritCavernsTopLeftKeystone': {frozenset({'ChargeJump'}), frozenset({'Bash'})}}, 'standard-dboost': {'DoubleJumpSkillTree': {frozenset({'Dash', ('HC', 0)})}, 'DoubleJumpAreaExp': {frozenset({'Dash', 'ChargeJump', ('HC', 0)}), frozenset({('HC', 0), 'Bash', 'Dash'}), frozenset({'ChargeJump', ('HC', 0), ('AC', 3), ('EC', 1)}), frozenset({'Bash', ('HC', 0), ('AC', 3), ('EC', 1)}), frozenset({'Bash', ('HC', 1)}), frozenset({'ChargeJump', ('HC', 1)})}, 'ForlornKeystone3': {frozenset({'ForlornKey', 'ChargeJump', ('HC', 1)})}, 'LowerGinsoKeystone1': {frozenset({('HC', 0)})}, 'LowerGinsoKeystone2': {frozenset({'ChargeJump', ('HC', 0)})}, 'GumoHideoutMapstone': {frozenset({'ChargeJump', ('HC', 1)})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Dash', 'ChargeJump', ('HC', 1)})}, 'MistyAbilityCell': {frozenset({'DoubleJump', 'WallJump', ('HC', 1)})}, 'GrottoEnergyDoorHealthCell': {frozenset({('EC', 2), 'WallJump'})}, 'BelowGrottoTeleporterHealthCell': {frozenset({('HC', 0), 'Bash', 'DoubleJump'}), frozenset({'Bash', ('HC', 0), 'WallJump'}), frozenset({'ChargeJump', ('HC', 0)})}, 'BelowGrottoTeleporterPlant': {frozenset({'ChargeFlame', ('HC', 1)}), frozenset({'Grenade', ('HC', 1)})}, 'GrottoSwampDrainAccessPlant': {frozenset({'ChargeFlame', 'Glide', ('HC', 1)}), frozenset({'ChargeFlame', 'DoubleJump', ('HC', 1)}), frozenset({'ChargeFlame', 'ChargeJump', ('HC', 1)}), frozenset({'ChargeFlame', 'WallJump', ('HC', 1)})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', ('HC', 0), 'Water'})}, 'InnerSwampDrainExp': {frozenset({'Grenade', 'Bash', ('HC', 1), 'Water'})}, 'TopGinsoLeftLowerExp': {frozenset({('HC', 0), 'DoubleJump'}), frozenset({'ChargeJump', ('HC', 0)})}, 'TopGinsoLeftUpperExp': {frozenset({('HC', 0), 'Dash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Dash', 'DoubleJump', ('HC', 0)}), frozenset({'Climb', 'Glide', 'DoubleJump', ('HC', 0)}), frozenset({('HC', 0), 'Glide', 'DoubleJump', 'WallJump'})}, 'TopGinsoRightPlant': {frozenset({'Grenade', 'DoubleJump', 'WallJump', ('HC', 0)}), frozenset({'Climb', 'Grenade', 'DoubleJump', ('HC', 0)})}, 'UpperGinsoLowerKeystone': {frozenset({'Bash', 'GinsoKey', ('HC', 0)}), frozenset({'GinsoKey', ('HC', 0), 'ChargeJump'}), frozenset({('HC', 0), 'GinsoKey', 'DoubleJump'})}, 'UpperGinsoRightKeystone': {frozenset({'GinsoKey', ('HC', 0), 'ChargeJump'})}, 'UpperGinsoUpperRightKeystone': {frozenset({'GinsoKey', ('HC', 0), 'ChargeJump'})}, 'UpperGinsoUpperLeftKeystone': {frozenset({'GinsoKey', ('HC', 0), 'ChargeJump'})}}, 'standard-core': {'DoubleJumpAreaExp': {frozenset({'ChargeJump', 'WallJump'})}, 'ForlornKeystone2': {frozenset({'ForlornKey', 'Dash', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'ForlornKey', 'Dash', 'WallJump'}), frozenset({'Climb', 'ForlornKey', 'Dash', 'DoubleJump'}), frozenset({'Glide', 'ForlornKey', 'Climb', 'Dash'})}, 'ForlornEntranceExp': {frozenset({'ForlornKey', 'Dash', 'WallJump', 'Open'}), frozenset({'Climb', 'ForlornKey', 'Dash', 'Open'})}, 'LowerGinsoKeystone1': {frozenset({'Grenade', 'Bash'})}, 'LowerGinsoKeystone2': {frozenset({'Grenade', 'Bash'})}, 'GladesLaserGrenade': {frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Grenade', 'Climb', 'Bash'}), frozenset({'Climb', 'Grenade', 'Glide', 'ChargeJump', 'DoubleJump'})}, 'GrenadeSkillTree': {frozenset({'Grenade', 'Bash'})}, 'GrenadeAreaExp': {frozenset({'Dash', 'DoubleJump'})}, 'GrenadeAreaAbilityCell': {frozenset({'Grenade', 'Bash'})}, 'GumoHideoutMapstone': {frozenset({'Climb'}), frozenset({'Grenade', 'Bash'})}, 'GumoHideoutRedirectAbilityCell': {frozenset({'Grenade', 'Bash'})}, 'SwampTeleporterAbilityCell': {frozenset({'Grenade', 'Bash', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Glide'})}, 'HoruFieldsHiddenExp': {frozenset({'Bash'})}, 'HoruLavaDrainedLeftExp': {frozenset({'Open', 'Dash', 'DoubleJump'})}, 'HoruL4LowerExp': {frozenset({'Climb', 'Stomp'})}, 'HoruR1EnergyCell': {frozenset({'Grenade', 'Bash'})}, 'HoruR3Plant': {frozenset({'ChargeFlame'})}, 'HoruR4DrainedExp': {frozenset({'Grenade', 'Bash', 'Climb'})}, 'HoruL1': {frozenset({'Glide', 'ChargeJump', 'Stomp', 'Bash'})}, 'HoruL3': {frozenset({'ChargeFlame', 'Bash', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Stomp'}), frozenset({'Glide', 'Bash', 'ChargeFlame', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'}), frozenset({'Glide', 'Bash', 'Climb', 'ChargeFlame'}), frozenset({'Grenade', 'Bash', 'ChargeFlame'})}, 'FarLeftGumoHideoutExp': {frozenset({'Climb', 'Bash', 'Grenade'})}, 'LeftSorrowKeystone1': {frozenset({'Dash'})}, 'LowerBlackrootLaserAbilityCell': {frozenset({'Dash', 'DoubleJump'})}, 'LowerBlackrootGrenadeThrow': {frozenset({'ChargeJump', 'DoubleJump'})}, 'GumoHideoutRightHangingExp': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'})}, 'SorrowSpikeKeystone': {frozenset({'Climb', 'Dash', 'DoubleJump'}), frozenset({'Dash', 'DoubleJump', 'WallJump'})}, 'SorrowHiddenKeystone': {frozenset({'Climb', 'Bash', 'Dash', 'DoubleJump'}), frozenset({'Bash', 'Dash', 'DoubleJump', 'WallJump'})}, 'SorrowHealthCell': {frozenset({'Bash', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'})}, 'SpiritCavernsAbilityCell': {frozenset({'DoubleJump', 'WallJump'})}, 'MistyFrogNookExp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Bash'})}, 'MistyPostClimbSpikeCave': {frozenset({'Glide', 'Bash'})}, 'MistyMortarCorridorUpperExp': {frozenset({'Grenade', 'Bash'})}, 'OuterSwampHealthCell': {frozenset({'Climb', 'DoubleJump'})}, 'HoruR1HangingExp': {frozenset({'Grenade', 'Bash'})}, 'HoruR2': {frozenset({'Glide', 'Stomp', 'Climb', 'Bash'}), frozenset({'Glide', 'Stomp', 'ChargeJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'WallJump', 'Bash'})}, 'StompAreaExp': {frozenset({'Climb', 'ChargeJump'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Bash', 'DoubleJump', 'Water'})}, 'GroveAboveSpiderWaterExp': {frozenset({'Bash', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Bash', 'ChargeJump'})}, 'GroveAboveSpiderWaterEnergyCell': {frozenset({'Dash', 'Grenade', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Grenade', 'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'AboveChargeFlameTreeExp': {frozenset({'Glide', 'Bash', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb'})}, 'GladesGrenadeTree': {frozenset({'Grenade', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Glide', 'Climb', 'Wind'}), frozenset({'Grenade', 'Glide', 'WallJump', 'Wind'})}, 'InnerSwampSwimRightKeystone': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'})}, 'TopGinsoLeftLowerExp': {frozenset({'Bash'})}, 'UpperGinsoRedirectLowerExp': {frozenset({'Climb', 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoRightKeystone': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Glide', 'GinsoKey', 'ChargeJump'}), frozenset({'GinsoKey', 'DoubleJump', 'ChargeJump'})}, 'UpperGinsoUpperRightKeystone': {frozenset({'Bash', 'GinsoKey'}), frozenset({'GinsoKey', 'DoubleJump', 'ChargeJump'})}, 'UpperGinsoUpperLeftKeystone': {frozenset({'Bash', 'GinsoKey'}), frozenset({'Glide', 'GinsoKey', 'ChargeJump'}), frozenset({'GinsoKey', 'DoubleJump', 'ChargeJump'})}, 'UpperGinsoEnergyCell': {frozenset({'Climb', 'GinsoKey', 'ChargeJump'})}, 'GrottoLasersRoofExp': {frozenset({'Climb', 'DoubleJump'})}, 'SpiritCavernsTopLeftKeystone': {frozenset({'ChargeJump'}), frozenset({'Bash'})}, 'ValleyRightBirdStompCell': {frozenset({'Stomp', 'DoubleJump'}), frozenset({'Climb', 'Stomp'}), frozenset({'Stomp', 'WallJump'})}, 'ValleyThreeBirdAbilityCell': {frozenset({'Dash', 'DoubleJump'})}, 'KuroPerchExp': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-lure': {'ForlornKeystone1': {frozenset({'ForlornKey', 'Bash'})}, 'GumoHideoutMiniboss': {frozenset({'Bash'})}, 'GroveWaterStompAbilityCell': {frozenset({'Bash', 'Water'})}, 'SorrowHealthCell': {frozenset({'Grenade', 'Glide', 'Stomp', 'Bash'}), frozenset({('AC', 6), 'Dash', ('EC', 2), 'Glide', 'Stomp'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump'}), frozenset({'Glide', 'Stomp', 'ChargeJump'})}}, 'gjump': {'GladesLaserGrenade': {frozenset({'Grenade', 'Climb', 'ChargeJump'})}, 'SwampTeleporterAbilityCell': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'HoruFieldsEnergyCell': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'HoruR4LaserExp': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'HoruL3': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'SorrowSpikeKeystone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'SorrowHiddenKeystone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'SorrowLowerLeftKeystone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'KuroPerchExp': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'MistyMortarCorridorUpperExp': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'StompAreaGrenadeExp': {frozenset({'Grenade', 'Climb', 'ChargeJump', 'Water'})}, 'SorrowMapstone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'GroveAboveSpiderWaterExp': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'GroveAboveSpiderWaterHealthCell': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'UpperSorrowLeftKeystone': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'ValleyThreeBirdAbilityCell': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'insane': {'GrenadeSkillTree': {frozenset({'WallJump'})}, 'ValleyRightBirdStompCell': {frozenset({'Bash'})}}, 'timed-level': {'LowerBlackrootGrenadeThrow': {frozenset({'Free'})}, 'SpiderSacEnergyDoor': {frozenset({('EC', 2)})}}} connection_rules = {'AboveChargeJumpArea': {'casual-core': {'SorrowTeleporter': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Glide', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'Grenade'})}}, 'expert-dboost': {'SorrowTeleporter': {frozenset({'Dash', 'ChargeJump', 'WallJump', ('HC', 2)})}, 'ChargeJumpArea': {frozenset({('HC', 3), 'Bash', 'ChargeJump'}), frozenset({('HC', 3), 'Dash', 'ChargeJump', ('AC', 6)})}}, 'master-core': {'SorrowTeleporter': {frozenset({'Bash'})}, 'ChargeJumpArea': {frozenset({'Bash'})}}, 'standard-lure': {'ChargeJumpArea': {frozenset({'Climb', 'Bash', 'Stomp'}), frozenset({'Bash', 'Stomp', 'WallJump'})}}, 'expert-core': {'ChargeJumpArea': {frozenset({'Climb', 'Bash', 'ChargeJump'}), frozenset({'Grenade', 'Bash', 'ChargeJump', 'WallJump'})}}, 'expert-abilities': {'ChargeJumpArea': {frozenset({('AC', 6), 'Dash', 'Stomp', 'WallJump'}), frozenset({'Climb', 'Dash', 'ChargeJump', ('AC', 6)}), frozenset({'Bash', 'ChargeJump', 'Dash', ('AC', 3)}), frozenset({'Climb', 'Dash', 'Stomp', ('AC', 6)})}}, 'gjump': {'ChargeJumpArea': {frozenset({'Climb', 'Dash', 'ChargeJump', 'Grenade'}), frozenset({'Climb', ('HC', 3), 'ChargeJump', 'Grenade'})}}, 'dbash': {'ChargeJumpArea': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}}}, 'BashTree': {'casual-core': {'BashTreeDoorClosed': {frozenset({'Open'})}, 'UpperGinsoRedirectArea': {frozenset({'Glide', 'ChargeJump', 'DoubleJump'}), frozenset({'Bash'}), frozenset({'Dash', 'ChargeJump', 'DoubleJump'})}}, 'standard-dboost': {'UpperGinsoRedirectArea': {frozenset({'ChargeJump', ('HC', 1)})}}, 'expert-dboost': {'UpperGinsoRedirectArea': {frozenset({'ChargeJump', ('HC', 0)})}}, 'expert-abilities': {'UpperGinsoRedirectArea': {frozenset({('AC', 6), 'Dash', 'ChargeJump'})}}, 'master-core': {'UpperGinsoRedirectArea': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Dash', 'DoubleJump'})}}, 'master-abilities': {'UpperGinsoRedirectArea': {frozenset({('AC', 12), 'DoubleJump'})}}}, 'BashTreeDoorClosed': {'casual-core': {'BashTreeDoorOpened': {frozenset({('KS', 4)})}}}, 'BashTreeDoorOpened': {'casual-core': {'GinsoMiniBossDoor': {frozenset({'Open', 'GinsoKey'})}, 'BashTree': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}}, 'master-core': {'BashTree': {frozenset({'DoubleJump'})}}}, 'BelowSunstoneArea': {'casual-core': {'SunstoneArea': {frozenset({'Glide', 'Stomp'})}, 'UpperSorrow': {frozenset({'Stomp'})}}, 'standard-core': {'SunstoneArea': {frozenset({'Climb', 'Glide', 'ChargeJump'})}, 'UpperSorrow': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-core': {'SunstoneArea': {frozenset({'Glide', 'Dash', 'ChargeJump'}), frozenset({'Grenade', 'Bash', 'ChargeJump', 'Glide'})}, 'UpperSorrow': {frozenset({'Grenade', 'Bash', 'ChargeJump'})}}, 'gjump': {'SunstoneArea': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'master-core': {'SunstoneArea': {frozenset({'Bash'})}, 'UpperSorrow': {frozenset({'Bash'})}}, 'master-dboost': {'SunstoneArea': {frozenset({('AC', 12), 'Climb', 'ChargeJump', 'DoubleJump', ('HC', 1)})}}, 'expert-abilities': {'UpperSorrow': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}}, 'BlackrootDarknessRoom': {'casual-core': {'DashArea': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}}, 'expert-core': {'DashArea': {frozenset({'DoubleJump'})}}, 'master-core': {'DashArea': {frozenset({'Bash'})}}}, 'BlackrootGrottoConnection': {'casual-core': {'SideFallCell': {frozenset({'Climb', 'Stomp', 'DoubleJump'}), frozenset({'Grenade', 'Stomp', 'Bash'}), frozenset({'Stomp', 'WallJump'}), frozenset({'Stomp', 'ChargeJump'})}}, 'standard-abilities': {'SideFallCell': {frozenset({'Climb', 'Stomp', 'Dash', ('AC', 3)})}}, 'expert-core': {'SideFallCell': {frozenset({'Climb', 'Stomp'})}}}, 'ChargeFlameAreaStump': {'casual-core': {'ChargeFlameSkillTreeChamber': {frozenset({'ChargeFlame'}), frozenset({'Grenade'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'})}}, 'standard-core': {'ChargeFlameSkillTreeChamber': {frozenset({'Stomp'})}}, 'expert-abilities': {'ChargeFlameSkillTreeChamber': {frozenset({'Dash', ('AC', 6)})}}, 'master-core': {'ChargeFlameSkillTreeChamber': {frozenset({'DoubleJump'})}}}, 'ChargeFlameSkillTreeChamber': {'casual-core': {'SpiritTreeRefined': {frozenset({'ChargeJump'})}, 'ChargeFlameAreaStump': {frozenset({'ChargeJump'}), frozenset({'ChargeFlame'}), frozenset({'Grenade'})}}, 'expert-abilities': {'ChargeFlameAreaStump': {frozenset({'Dash', ('AC', 6)})}}}, 'ChargeJumpArea': {'casual-core': {'AboveChargeJumpArea': {frozenset({'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'})}, 'ChargeJumpDoor': {frozenset({'Open'})}}, 'gjump': {'AboveChargeJumpArea': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'expert-dboost': {'AboveChargeJumpArea': {frozenset({'Bash', 'ChargeJump', 'WallJump', ('HC', 2)}), frozenset({'Dash', 'ChargeJump', ('HC', 2)})}}, 'expert-abilities': {'AboveChargeJumpArea': {frozenset({'Climb', 'Dash', 'ChargeJump', ('AC', 6)})}}, 'master-core': {'AboveChargeJumpArea': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}}}, 'ChargeJumpDoor': {'casual-core': {'ChargeJumpDoorOpen': {frozenset({('KS', 4)})}}}, 'ChargeJumpDoorOpen': {'casual-core': {'ChargeJumpArea': {frozenset({'Glide'})}}, 'master-dboost': {'ChargeJumpArea': {frozenset({('AC', 12), 'Dash', 'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 12), 'Dash', ('HC', 1), 'Grenade', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({('HC', 4), ('AC', 12), 'Grenade', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 7)}), frozenset({('HC', 10), ('AC', 12), 'Grenade', 'Bash', 'DoubleJump', 'WallJump'})}, 'ChargeJumpDoorOpenLeft': {frozenset({'ChargeJump', ('HC', 2)})}}, 'expert-dboost': {'ChargeJumpDoorOpenLeft': {frozenset({('HC', 3), 'ChargeJump'})}}, 'master-lure': {'ChargeJumpDoorOpenLeft': {frozenset({'Bash'})}}}, 'ChargeJumpDoorOpenLeft': {'casual-core': {'UpperSorrow': {frozenset({'Glide'})}}, 'master-dboost': {'UpperSorrow': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump', ('HC', 7)}), frozenset({('AC', 6), ('HC', 6), 'Dash', ('EC', 2), 'ChargeJump'}), frozenset({('HC', 4), ('AC', 12), 'Dash', ('EC', 2), 'ChargeJump'})}}, 'master-lure': {'UpperSorrow': {frozenset({'Bash'})}}}, 'DashArea': {'casual-core': {'DashPlantAccess': {frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide', 'WallJump'})}, 'GrenadeAreaAccess': {frozenset({'Stomp', 'Dash'}), frozenset({'Grenade', 'Stomp', 'Bash'}), frozenset({'Stomp', 'ChargeJump'})}, 'RazielNoArea': {frozenset({'Grenade', 'Dash', 'Bash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Dash', 'ChargeJump'}), frozenset({'Climb', 'Dash', 'DoubleJump'})}}, 'standard-abilities': {'DashPlantAccess': {frozenset({'Climb', 'Dash', 'DoubleJump', ('AC', 3)}), frozenset({'Dash', ('AC', 3), 'DoubleJump', 'WallJump'})}, 'RazielNoArea': {frozenset({'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Climb', 'Dash', ('AC', 3)}), frozenset({'WallJump'})}}, 'expert-core': {'DashPlantAccess': {frozenset({'Grenade', 'ChargeJump'}), frozenset({'Grenade', 'Glide'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Grenade', 'DoubleJump'})}, 'GrenadeAreaAccess': {frozenset({'Stomp'})}}, 'expert-abilities': {'DashPlantAccess': {frozenset({'Climb', 'Dash', ('AC', 6), ('EC', 2)}), frozenset({'Grenade', 'Dash', ('AC', 3)}), frozenset({'ChargeFlame', 'Dash', ('AC', 6), 'WallJump'}), frozenset({('EC', 2), 'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6), 'ChargeFlame'})}, 'RazielNoArea': {frozenset({'Climb'})}}, 'master-core': {'DashPlantAccess': {frozenset({'Glide', 'DoubleJump'}), frozenset({'Bash'}), frozenset({'Dash', 'DoubleJump'})}, 'GrenadeAreaAccess': {frozenset({'Bash'})}}, 'master-abilities': {'DashPlantAccess': {frozenset({'Climb', 'ChargeFlame', ('AC', 3)}), frozenset({'ChargeFlame', ('AC', 3), 'WallJump'}), frozenset({('AC', 12), 'DoubleJump'}), frozenset({'ChargeFlame', 'DoubleJump', ('AC', 3)})}, 'RazielNoArea': {frozenset({'DoubleJump'})}}, 'standard-core': {'GrenadeAreaAccess': {frozenset({'Climb', 'ChargeJump'})}, 'RazielNoArea': {frozenset({'Grenade', 'Bash'})}}, 'glitched': {'GrenadeAreaAccess': {frozenset({'Free'})}}, 'insane': {'GrenadeAreaAccess': {frozenset({'Free'})}}}, 'DeathGauntlet': {'casual-core': {'DeathGauntletMoat': {frozenset({'Water'})}, 'DeathGauntletDoor': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Glide'})}, 'DeathGauntletRoof': {frozenset({'ChargeJump'})}, 'MoonGrotto': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}}, 'expert-dboost': {'DeathGauntletMoat': {frozenset({('HC', 1)})}}, 'master-dboost': {'DeathGauntletMoat': {frozenset({('HC', 0)})}}, 'expert-core': {'DeathGauntletRoofPlantAccess': {frozenset({'ChargeFlame', 'Climb', 'DoubleJump'}), frozenset({'ChargeFlame', 'Bash', 'WallJump'}), frozenset({'ChargeFlame', 'Bash', 'Grenade'}), frozenset({'ChargeFlame', 'DoubleJump', 'WallJump'}), frozenset({'ChargeFlame', 'Bash', 'Climb'})}}, 'master-core': {'DeathGauntletRoofPlantAccess': {frozenset({'ChargeFlame', 'DoubleJump'})}}, 'master-abilities': {'DeathGauntletRoofPlantAccess': {frozenset({'ChargeFlame', ('AC', 3)})}}, 'master-lure': {'MoonGrotto': {frozenset({'Dash', ('AC', 6), ('EC', 1)}), frozenset({'Bash'})}, 'MoonGrottoAboveTeleporter': {frozenset({'Bash'})}}}, 'DeathGauntletDoor': {'casual-core': {'DeathGauntletDoorOpened': {frozenset({('EC', 4)})}}, 'glitched': {'DeathGauntletDoorOpened': {frozenset({('EC', 3)})}}, 'timed-level': {'DeathGauntletDoorOpened': {frozenset({('EC', 2)})}}}, 'DeathGauntletDoorOpened': {'casual-core': {'DeathGauntlet': {frozenset({'Climb', 'Glide', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash'}), frozenset({'WallJump', 'Water'}), frozenset({'Climb', 'Water'}), frozenset({'Bash', 'Water'}), frozenset({'Glide', 'DoubleJump', 'WallJump'})}, 'DeathGauntletMoat': {frozenset({'Water'})}}, 'standard-dboost': {'DeathGauntlet': {frozenset({'Climb', ('HC', 1)}), frozenset({'WallJump', ('HC', 1)}), frozenset({'Bash', ('HC', 1)})}}, 'expert-dboost': {'DeathGauntlet': {frozenset({'Climb', ('HC', 0)}), frozenset({'Bash', ('HC', 0)}), frozenset({('HC', 0), 'WallJump'})}, 'DeathGauntletMoat': {frozenset({('HC', 2)})}}, 'expert-abilities': {'DeathGauntlet': {frozenset({'Dash', ('AC', 6), ('EC', 1)})}}, 'master-core': {'DeathGauntlet': {frozenset({'DoubleJump'})}}, 'master-dboost': {'DeathGauntletMoat': {frozenset({('HC', 1)})}}}, 'DeathGauntletRoof': {'casual-core': {'DeathGauntlet': {frozenset({'Stomp'})}}, 'standard-lure': {'DeathGauntlet': {frozenset({'Free'})}}}, 'DoubleJumpKeyDoor': {'casual-core': {'DoubleJumpKeyDoorOpened': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}}, 'expert-core': {'DoubleJumpKeyDoorOpened': {frozenset({'DoubleJump'})}}}, 'ForlornGravityRoom': {'casual-core': {'ForlornMapArea': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'ForlornInnerDoor': {frozenset({'Climb', 'Glide', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Bash'}), frozenset({'Glide', 'DoubleJump', 'WallJump'})}}, 'master-core': {'ForlornMapArea': {frozenset({'DoubleJump'})}}, 'master-lure': {'ForlornMapArea': {frozenset({'Bash'})}}, 'standard-dboost': {'ForlornInnerDoor': {frozenset({('HC', 1)})}}, 'standard-core': {'ForlornInnerDoor': {frozenset({'Dash', 'DoubleJump'})}}, 'standard-abilities': {'ForlornInnerDoor': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'expert-core': {'ForlornInnerDoor': {frozenset({'ChargeJump'})}}, 'master-dboost': {'ForlornInnerDoor': {frozenset({('AC', 12), ('HC', 0)})}}}, 'ForlornInnerDoor': {'casual-core': {'ForlornOuterDoor': {frozenset({'ForlornKey'})}, 'ForlornOrbPossession': {frozenset({'Climb', 'Glide', 'Open'}), frozenset({'Open', 'ChargeJump'}), frozenset({'Grenade', 'Bash', 'Open'}), frozenset({'Glide', 'WallJump', 'Open'}), frozenset({'Open', 'DoubleJump'})}, 'ForlornGravityRoom': {frozenset({'Climb', 'Glide', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Glide', 'DoubleJump', 'WallJump'})}}, 'standard-core': {'ForlornOrbPossession': {frozenset({'Dash', 'WallJump', 'Open'}), frozenset({'Climb', 'Dash', 'Open'})}, 'ForlornGravityRoom': {frozenset({'Climb', 'Dash', 'DoubleJump'}), frozenset({'Dash', 'DoubleJump', 'WallJump'})}}, 'expert-core': {'ForlornOrbPossession': {frozenset({'Open'})}, 'ForlornGravityRoom': {frozenset({'ChargeJump'})}}, 'standard-dboost': {'ForlornGravityRoom': {frozenset({'DoubleJump', 'WallJump', ('HC', 1)}), frozenset({'ChargeJump', ('HC', 1)}), frozenset({'Climb', 'DoubleJump', ('HC', 1)})}}, 'standard-abilities': {'ForlornGravityRoom': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'expert-dboost': {'ForlornGravityRoom': {frozenset({'WallJump', ('HC', 1)})}}, 'master-dboost': {'ForlornGravityRoom': {frozenset({('AC', 12), ('HC', 0), 'WallJump'})}}}, 'ForlornKeyDoor': {'casual-core': {'ForlornLaserRoom': {frozenset({'ForlornKey', ('KS', 4)})}}}, 'ForlornLaserRoom': {'casual-core': {'ForlornStompDoor': {frozenset({'Grenade', 'Stomp', 'Bash'}), frozenset({'Glide', 'Stomp', 'ChargeJump'})}}, 'standard-abilities': {'ForlornStompDoor': {frozenset({'Dash', 'Glide', ('AC', 3), 'Stomp', 'DoubleJump', ('HC', 1)}), frozenset({'Dash', ('HC', 1), 'Stomp', 'ChargeJump', ('AC', 3)}), frozenset({'Dash', 'Stomp', 'ChargeJump', 'DoubleJump', ('AC', 3)})}}, 'standard-dboost': {'ForlornStompDoor': {frozenset({'Stomp', 'ChargeJump', 'DoubleJump', ('HC', 1)})}}, 'expert-abilities': {'ForlornStompDoor': {frozenset({'Stomp', ('AC', 6), 'Dash', 'DoubleJump'}), frozenset({'Climb', 'Stomp', ('AC', 6), 'Dash'}), frozenset({('AC', 6), 'Stomp', 'ChargeJump', 'Dash'}), frozenset({'Stomp', ('AC', 6), 'Dash', 'WallJump'})}}, 'master-abilities': {'ForlornStompDoor': {frozenset({'Glide', 'Stomp', ('AC', 12), 'DoubleJump'}), frozenset({'Stomp', 'ChargeJump', 'DoubleJump', ('AC', 12)})}}, 'master-lure': {'ForlornStompDoor': {frozenset({'Stomp', 'Bash'})}}, 'gjump': {'ForlornStompDoor': {frozenset({'Climb', 'Stomp', 'ChargeJump', 'Grenade'})}}}, 'ForlornMapArea': {'casual-core': {'ForlornTeleporter': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'})}, 'ForlornPlantAccess': {frozenset({'Grenade', 'ForlornKey', 'WallJump', 'Bash'}), frozenset({'ForlornKey', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'ForlornKey', 'ChargeJump'}), frozenset({'Grenade', 'ForlornKey', 'Climb', 'Bash'})}}, 'standard-abilities': {'ForlornTeleporter': {frozenset({'Glide', 'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', 'Glide', ('AC', 3)}), frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'standard-dboost': {'ForlornTeleporter': {frozenset({'ChargeJump', ('HC', 1)})}}, 'master-core': {'ForlornTeleporter': {frozenset({'DoubleJump'})}, 'ForlornPlantAccess': {frozenset({'Grenade', 'ForlornKey', 'DoubleJump', 'Bash'}), frozenset({'ForlornKey', 'ChargeJump', 'DoubleJump'})}}, 'master-lure': {'ForlornTeleporter': {frozenset({'Bash'})}}, 'master-dboost': {'ForlornTeleporter': {frozenset({('AC', 12), 'ChargeJump', ('HC', 0)})}}}, 'ForlornOrbPossession': {'casual-core': {'ForlornPlantAccess': {frozenset({'ForlornKey'})}, 'ForlornInnerDoor': {frozenset({'Climb', 'Glide', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Bash'}), frozenset({'Glide', 'DoubleJump', 'WallJump'})}}, 'standard-dboost': {'ForlornInnerDoor': {frozenset({('HC', 1)})}}, 'standard-core': {'ForlornInnerDoor': {frozenset({'Dash', 'DoubleJump'})}}, 'standard-abilities': {'ForlornInnerDoor': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'expert-core': {'ForlornInnerDoor': {frozenset({'ChargeJump'})}}, 'master-dboost': {'ForlornInnerDoor': {frozenset({('AC', 12), ('HC', 0)})}}}, 'ForlornStompDoor': {'casual-core': {'RightForlorn': {frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}}, 'standard-abilities': {'RightForlorn': {frozenset({'Dash', 'ChargeJump', ('AC', 3)}), frozenset({'Climb', 'Dash', 'DoubleJump', ('AC', 3)}), frozenset({'Dash', ('AC', 3), 'DoubleJump', 'WallJump'})}}, 'standard-dboost': {'RightForlorn': {frozenset({'DoubleJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', 'DoubleJump', ('HC', 1)})}}, 'expert-dboost': {'RightForlorn': {frozenset({'Climb', ('HC', 1)}), frozenset({'WallJump', ('HC', 1)})}}, 'master-dboost': {'RightForlorn': {frozenset({'Climb', ('AC', 12), ('HC', 0)}), frozenset({('AC', 12), ('HC', 0), 'WallJump'})}}, 'master-lure': {'RightForlorn': {frozenset({'Bash'})}}, 'master-abilities': {'RightForlorn': {frozenset({('AC', 12), 'DoubleJump'})}}}, 'ForlornTeleporter': {'casual-core': {'ForlornOrbPossession': {frozenset({'ForlornKey', 'Open'})}, 'ForlornMapArea': {frozenset({'Grenade', 'Bash'}), frozenset({'Glide'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}}}, 'GinsoEscape': {'casual-core': {'GinsoEscapeComplete': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'})}}, 'standard-core': {'GinsoEscapeComplete': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}}, 'expert-core': {'GinsoEscapeComplete': {frozenset({'Climb', 'ChargeJump', 'DoubleJump'})}}, 'expert-dboost': {'GinsoEscapeComplete': {frozenset({'Climb', 'ChargeJump', ('HC', 0)}), frozenset({('AC', 6), ('HC', 0), 'Dash', 'ChargeJump', 'DoubleJump'}), frozenset({'ChargeJump', ('HC', 6), 'WallJump'})}}, 'dbash': {'GinsoEscapeComplete': {frozenset({'Bash'})}}, 'master-dboost': {'GinsoEscapeComplete': {frozenset({('HC', 3), ('AC', 12), 'DoubleJump', 'WallJump'}), frozenset({'Climb', ('AC', 12), 'DoubleJump', ('HC', 7)}), frozenset({('HC', 4), 'ChargeJump', 'DoubleJump'})}}, 'insane': {'GinsoEscapeComplete': {frozenset({('HC', 9), ('AC', 12), 'DoubleJump'})}}}, 'GinsoInnerDoor': {'casual-core': {'LowerGinsoTree': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}}, 'master-core': {'LowerGinsoTree': {frozenset({'DoubleJump'})}}, 'master-abilities': {'LowerGinsoTree': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)})}}}, 'GinsoMiniBossDoor': {'casual-core': {'BashTreeDoorClosed': {frozenset({'Free'})}}}, 'GinsoTeleporter': {'casual-core': {'TopGinsoTree': {frozenset({'Bash', 'GinsoKey', 'DoubleJump', 'WallJump'}), frozenset({'GinsoKey', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'GinsoKey', 'DoubleJump'}), frozenset({'Climb', 'GinsoKey', 'ChargeJump'})}, 'UpperGinsoDoorClosed': {frozenset({'Open'})}}, 'standard-core': {'TopGinsoTree': {frozenset({'Grenade', 'GinsoKey', 'DoubleJump', 'WallJump'}), frozenset({'ChargeFlame', 'GinsoKey', 'DoubleJump', 'WallJump'})}}, 'expert-core': {'TopGinsoTree': {frozenset({'Stomp', 'GinsoKey', 'DoubleJump', 'WallJump'}), frozenset({'GinsoKey', 'ChargeJump'})}}, 'master-abilities': {'TopGinsoTree': {frozenset({'ChargeFlame', ('AC', 12), 'GinsoKey', 'DoubleJump'}), frozenset({'Grenade', ('AC', 12), 'GinsoKey', 'DoubleJump'}), frozenset({'Stomp', 'GinsoKey', 'DoubleJump', ('AC', 12)})}}}, 'GladesLaserArea': {'casual-core': {'MidSpiritCaverns': {frozenset({('EC', 4), 'DoubleJump'}), frozenset({('EC', 4), 'WallJump'}), frozenset({'Grenade', 'Bash', ('EC', 4)}), frozenset({'Climb', ('EC', 4)}), frozenset({'ChargeJump', ('EC', 4)})}}, 'expert-core': {'MidSpiritCaverns': {frozenset({'Dash', ('EC', 4)})}}, 'dbash': {'MidSpiritCaverns': {frozenset({'Bash', ('EC', 4)})}}, 'timed-level': {'MidSpiritCaverns': {frozenset({'Climb', ('EC', 2)}), frozenset({('EC', 2), 'WallJump'}), frozenset({('EC', 2), 'DoubleJump'}), frozenset({('EC', 2), 'Dash'}), frozenset({('EC', 2), 'ChargeJump'}), frozenset({('EC', 2), 'Bash'})}}}, 'GladesMain': {'casual-core': {'GladesMainAttic': {frozenset({'ChargeJump'}), frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'GladesLaserArea': {frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Glide', 'Bash', 'DoubleJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'})}, 'LowerChargeFlameArea': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}}, 'standard-core': {'GladesMainAttic': {frozenset({'DoubleJump', 'WallJump'})}}, 'expert-core': {'GladesMainAttic': {frozenset({'Climb', 'DoubleJump'}), frozenset({'Bash'})}, 'GladesLaserArea': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}}, 'expert-abilities': {'GladesMainAttic': {frozenset({'Dash', ('AC', 6)})}, 'GladesLaserArea': {frozenset({'Dash', ('AC', 6)})}, 'LowerChargeFlameArea': {frozenset({'Dash', ('AC', 6)})}}, 'dbash': {'GladesMainAttic': {frozenset({'Bash'})}, 'GladesLaserArea': {frozenset({'Bash'})}}, 'master-core': {'GladesMainAttic': {frozenset({'DoubleJump'})}}}, 'GladesMainAttic': {'glitched': {'LowerChargeFlameArea': {frozenset({'Dash'})}}}, 'GrenadeAreaAccess': {'casual-core': {'GrenadeArea': {frozenset({'Dash'})}, 'LowerBlackroot': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'})}}, 'expert-core': {'GrenadeArea': {frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'})}}, 'gjump': {'GrenadeArea': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'glitched': {'GrenadeArea': {frozenset({'Free'})}}, 'insane': {'GrenadeArea': {frozenset({'Free'})}}, 'casual-dboost': {'LowerBlackroot': {frozenset({'Free'})}}, 'standard-core': {'LowerBlackroot': {frozenset({'Grenade', 'Bash'})}}, 'expert-abilities': {'LowerBlackroot': {frozenset({'Dash', ('AC', 3)})}}, 'dbash': {'LowerBlackroot': {frozenset({'Bash'})}}}, 'GumoHideout': {'casual-core': {'DoubleJumpKeyDoor': {frozenset({('KS', 2)})}, 'LeftGumoHideout': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'ChargeJump'})}, 'SideFallCell': {frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'Bash', 'Grenade'}), frozenset({'ChargeJump', 'WallJump'})}}, 'expert-core': {'LeftGumoHideout': {frozenset({'ChargeJump'})}}, 'master-core': {'LeftGumoHideout': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}, 'LowerLeftGumoHideout': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'}), frozenset({'DoubleJump'})}}, 'master-abilities': {'LeftGumoHideout': {frozenset({('AC', 12), 'DoubleJump'})}}, 'dbash': {'SideFallCell': {frozenset({'Bash'})}}}, 'GumoHideoutRedirectArea': {'casual-core': {'GumoHideoutRedirectEnergyVault': {frozenset({('EC', 4)})}}, 'glitched': {'GumoHideoutRedirectEnergyVault': {frozenset({'Free'})}}}, 'HollowGrove': {'casual-core': {'SpiderWaterArea': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Water'}), frozenset({'DoubleJump'})}, 'SwampTeleporter': {frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'})}, 'OuterSwampUpperArea': {frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'})}, 'HoruFields': {frozenset({'Bash'})}, 'Iceless': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}}, 'standard-core': {'SpiderWaterArea': {frozenset({'Bash'})}, 'HoruFields': {frozenset({'Climb', 'Stomp', 'DoubleJump'}), frozenset({'Stomp', 'WallJump'}), frozenset({'Stomp', 'ChargeJump'})}}, 'master-core': {'SpiderWaterArea': {frozenset({'Free'})}, 'SwampTeleporter': {frozenset({'DoubleJump'})}, 'OuterSwampUpperArea': {frozenset({'DoubleJump'})}, 'HoruFields': {frozenset({'DoubleJump'})}, 'Iceless': {frozenset({'DoubleJump'}), frozenset({'WallJump'})}}, 'standard-abilities': {'HoruFields': {frozenset({'Climb', 'Stomp', 'Dash', ('AC', 3)})}}, 'expert-core': {'HoruFields': {frozenset({'ChargeJump'}), frozenset({'WallJump'})}}, 'expert-abilities': {'HoruFields': {frozenset({'Climb', 'Dash', ('AC', 3)})}, 'Iceless': {frozenset({'Dash', ('AC', 6)})}}, 'standard-lure': {'Iceless': {frozenset({'Bash'})}}, 'master-lure': {'MoonGrottoStompPlantAccess': {frozenset({'Dash', ('AC', 6)}), frozenset({'WallJump', ('HC', 1)}), frozenset({'ChargeJump', ('HC', 1)}), frozenset({'DoubleJump'}), frozenset({'Glide', 'WallJump'})}}}, 'HoruBasement': {'casual-core': {'HoruEscapeOuterDoor': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Dash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}}}, 'HoruFields': {'casual-core': {'HoruFieldsPushBlock': {frozenset({'Glide', 'Bash'}), frozenset({'Bash', 'DoubleJump'})}, 'HoruOuterDoor': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb'})}}, 'standard-core': {'HoruFieldsPushBlock': {frozenset({'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'Glide', 'ChargeJump', 'DoubleJump'})}, 'HoruOuterDoor': {frozenset({'Grenade', 'Bash'}), frozenset({'Glide', 'ChargeJump'})}}, 'standard-abilities': {'HoruFieldsPushBlock': {frozenset({'Climb', 'Dash', 'Glide', 'ChargeJump', ('AC', 3)}), frozenset({'WallJump', 'Dash', 'Glide', 'ChargeJump', ('AC', 3)})}}, 'expert-core': {'HoruFieldsPushBlock': {frozenset({'Glide', 'ChargeJump', 'DoubleJump'})}}, 'expert-abilities': {'HoruFieldsPushBlock': {frozenset({('AC', 6), 'Dash', 'ChargeJump', ('EC', 4)}), frozenset({('AC', 6), 'Dash', ('EC', 3), 'Glide', 'ChargeJump'})}}, 'dbash': {'HoruFieldsPushBlock': {frozenset({'Bash'})}}, 'master-abilities': {'HoruFieldsPushBlock': {frozenset({('EC', 4), ('AC', 12), 'Climb', 'Dash', 'DoubleJump'}), frozenset({('AC', 12), 'Dash', ('EC', 5), 'DoubleJump', 'WallJump'})}, 'HoruOuterDoor': {frozenset({('AC', 12), 'Dash', ('EC', 3), 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'})}}, 'gjump': {'HoruFieldsPushBlock': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}, 'HoruOuterDoor': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'master-core': {'HoruOuterDoor': {frozenset({'Bash'})}}}, 'HoruFieldsPushBlock': {'master-lure': {'HollowGrove': {frozenset({'Bash'})}}}, 'HoruInnerDoor': {'casual-core': {'HoruMapLedge': {frozenset({'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'Bash', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'Climb', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb', 'ChargeJump'})}, 'L1OuterDoor': {frozenset({'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'Bash', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'Climb', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb', 'ChargeJump'})}, 'L2OuterDoor': {frozenset({'ChargeJump', 'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Stomp', 'ChargeJump', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'ChargeJump', 'Glide', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Open', 'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Stomp', 'ChargeJump', 'DoubleJump', 'Bash'}), frozenset({'Open', 'Climb', 'Glide', 'ChargeJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'Open', 'Climb', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Open', 'Glide', 'ChargeJump', 'WallJump', 'Bash'})}, 'L3OuterDoor': {frozenset({'ChargeJump', 'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Stomp', 'ChargeJump', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'ChargeJump', 'Glide', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Open', 'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Stomp', 'ChargeJump', 'DoubleJump', 'Bash'}), frozenset({'Open', 'Climb', 'Glide', 'ChargeJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'Open', 'Climb', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Open', 'Glide', 'ChargeJump', 'WallJump', 'Bash'})}, 'L4OuterDoor': {frozenset({'ChargeJump', 'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Open', 'ChargeJump'}), frozenset({'Stomp', 'ChargeJump', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'Open', 'Bash'}), frozenset({'ChargeJump', 'Glide', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Climb', 'Stomp', 'ChargeJump', 'DoubleJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump', 'Bash'})}, 'R1OuterDoor': {frozenset({'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'Bash', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'Climb', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb', 'ChargeJump'})}, 'R2OuterDoor': {frozenset({'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'Bash', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Open', 'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Open', 'Climb', 'Glide', 'ChargeJump', 'Bash'}), frozenset({'Glide', 'Bash', 'Climb', 'DoubleJump'}), frozenset({'Open', 'Climb', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Open', 'Glide', 'ChargeJump', 'WallJump', 'Bash'}), frozenset({'Glide', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb', 'ChargeJump'})}, 'R3OuterDoor': {frozenset({'ChargeJump', 'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Stomp', 'ChargeJump', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'ChargeJump', 'Glide', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Open', 'Bash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Stomp', 'ChargeJump', 'DoubleJump', 'Bash'}), frozenset({'Open', 'Climb', 'Glide', 'ChargeJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'Open', 'Climb', 'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Open', 'Glide', 'ChargeJump', 'WallJump', 'Bash'})}, 'R4OuterDoor': {frozenset({'ChargeJump', 'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Stomp', 'ChargeJump', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'Grenade', 'Open', 'Bash'}), frozenset({'Open', 'ChargeJump', 'DoubleJump'}), frozenset({'ChargeJump', 'Glide', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Open', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Stomp', 'ChargeJump', 'DoubleJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'Climb', 'Open', 'ChargeJump'})}, 'HoruBasement': {frozenset({'ChargeJump', 'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Stomp', 'ChargeJump', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'Open'}), frozenset({'ChargeJump', 'Glide', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Climb', 'Stomp', 'ChargeJump', 'DoubleJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump', 'Bash'})}, 'HoruTeleporter': {frozenset({'ChargeJump', 'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Stomp', 'ChargeJump', 'DoubleJump', 'WallJump', 'Bash'}), frozenset({'Open'}), frozenset({'ChargeJump', 'Glide', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Glide', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Climb', 'Stomp', 'ChargeJump', 'DoubleJump', 'Bash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump', 'Bash'})}}, 'expert-core': {'HoruMapLedge': {frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Grenade', 'Bash', 'WallJump'})}, 'L1OuterDoor': {frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Grenade', 'Bash', 'WallJump'})}, 'L2OuterDoor': {frozenset({'Grenade', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Grenade', 'Stomp', 'Climb', 'Bash'})}, 'L3OuterDoor': {frozenset({'Grenade', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Grenade', 'Stomp', 'Climb', 'Bash'})}, 'L4OuterDoor': {frozenset({'Grenade', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Grenade', 'Stomp', 'Climb', 'Bash'})}, 'R1OuterDoor': {frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Grenade', 'Bash', 'WallJump'})}, 'R2OuterDoor': {frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Grenade', 'Bash', 'WallJump'})}, 'R3OuterDoor': {frozenset({'Grenade', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Grenade', 'Stomp', 'Climb', 'Bash'})}, 'R4OuterDoor': {frozenset({'Grenade', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Grenade', 'Stomp', 'Climb', 'Bash'})}, 'HoruBasement': {frozenset({'Free'})}, 'HoruTeleporter': {frozenset({'Grenade', 'Stomp', 'WallJump', 'Bash'}), frozenset({'Grenade', 'Stomp', 'Climb', 'Bash'})}}, 'dbash': {'HoruMapLedge': {frozenset({'Bash'})}, 'L1OuterDoor': {frozenset({'Bash'})}, 'L2OuterDoor': {frozenset({'Open', 'Bash'})}, 'L3OuterDoor': {frozenset({'Open', 'Bash'})}, 'R1OuterDoor': {frozenset({'Bash'})}, 'R2OuterDoor': {frozenset({'Open', 'Bash'})}, 'R3OuterDoor': {frozenset({'Open', 'Bash'})}, 'R4OuterDoor': {frozenset({'Open', 'Bash'})}}, 'master-dboost': {'HoruMapLedge': {frozenset({('AC', 12), ('HC', 1), 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'L1OuterDoor': {frozenset({('AC', 12), ('HC', 5), 'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'L2OuterDoor': {frozenset({'ChargeJump', ('AC', 12), ('HC', 5), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'})}, 'L3OuterDoor': {frozenset({'ChargeJump', ('AC', 12), ('HC', 5), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'})}, 'L4OuterDoor': {frozenset({'ChargeJump', ('AC', 12), ('HC', 5), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'})}, 'R1OuterDoor': {frozenset({('AC', 12), ('HC', 5), 'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'R2OuterDoor': {frozenset({('AC', 12), ('HC', 5), 'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'R3OuterDoor': {frozenset({'ChargeJump', ('AC', 12), ('HC', 5), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'})}, 'R4OuterDoor': {frozenset({'ChargeJump', ('AC', 12), ('HC', 5), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'})}, 'HoruBasement': {frozenset({'ChargeJump', ('AC', 12), ('HC', 5), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'})}, 'HoruTeleporter': {frozenset({'ChargeJump', ('AC', 12), ('HC', 5), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'})}}, 'standard-core': {'L2OuterDoor': {frozenset({'Glide', 'Open', 'DoubleJump', 'Bash'}), frozenset({'Climb', 'Open', 'ChargeJump', 'Bash'}), frozenset({'Grenade', 'Open', 'Bash'}), frozenset({'Open', 'ChargeJump', 'WallJump', 'Bash'}), frozenset({'Glide', 'Open', 'ChargeJump', 'WallJump'}), frozenset({'Open', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'L3OuterDoor': {frozenset({'Glide', 'Open', 'DoubleJump', 'Bash'}), frozenset({'Climb', 'Open', 'ChargeJump', 'Bash'}), frozenset({'Grenade', 'Open', 'Bash'}), frozenset({'Open', 'ChargeJump', 'WallJump', 'Bash'}), frozenset({'Glide', 'Open', 'ChargeJump', 'WallJump'}), frozenset({'Open', 'ChargeJump', 'DoubleJump', 'WallJump'})}, 'R2OuterDoor': {frozenset({'Glide', 'Open', 'DoubleJump', 'Bash'}), frozenset({'Open', 'Dash', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Open', 'ChargeJump', 'Bash'}), frozenset({'Grenade', 'Open', 'Bash'}), frozenset({'Open', 'Dash', 'Glide', 'ChargeJump', 'WallJump'}), frozenset({'Open', 'ChargeJump', 'WallJump', 'Bash'})}, 'R3OuterDoor': {frozenset({'Glide', 'Open', 'DoubleJump', 'Bash'}), frozenset({'Climb', 'Open', 'ChargeJump', 'Bash'}), frozenset({'Grenade', 'Open', 'Bash'}), frozenset({'Open', 'ChargeJump', 'WallJump', 'Bash'}), frozenset({'Glide', 'Open', 'ChargeJump', 'WallJump'}), frozenset({'Open', 'ChargeJump', 'DoubleJump', 'WallJump'})}}, 'expert-dboost': {'L2OuterDoor': {frozenset({'ChargeJump', 'WallJump', ('HC', 2)})}, 'L3OuterDoor': {frozenset({'ChargeJump', 'WallJump', ('HC', 2)})}, 'R3OuterDoor': {frozenset({'ChargeJump', 'WallJump', ('HC', 2)})}}, 'expert-abilities': {'L2OuterDoor': {frozenset({'Open', ('AC', 6), 'Dash', 'WallJump'}), frozenset({'Climb', 'Open', ('AC', 6), 'Dash'})}, 'L3OuterDoor': {frozenset({'Open', ('AC', 6), 'Dash', 'WallJump'}), frozenset({'Climb', 'Open', ('AC', 6), 'Dash'})}, 'L4OuterDoor': {frozenset({'Open', ('AC', 6), 'Dash'})}, 'R2OuterDoor': {frozenset({'Open', ('AC', 6), 'Dash', 'WallJump'}), frozenset({'Climb', 'Open', ('AC', 6), 'Dash'})}, 'R3OuterDoor': {frozenset({'Open', ('AC', 6), 'Dash', 'WallJump'}), frozenset({'Climb', 'Open', ('AC', 6), 'Dash'})}, 'R4OuterDoor': {frozenset({'Open', ('AC', 6), 'Dash'})}}, 'master-abilities': {'L2OuterDoor': {frozenset({'Open', 'ChargeJump', 'DoubleJump', ('AC', 12)})}, 'L3OuterDoor': {frozenset({'Open', 'ChargeJump', 'DoubleJump', ('AC', 12)})}, 'R2OuterDoor': {frozenset({'Open', 'ChargeJump', 'DoubleJump', ('AC', 12)})}, 'R3OuterDoor': {frozenset({'Open', 'ChargeJump', 'DoubleJump', ('AC', 12)})}}, 'gjump': {'L2OuterDoor': {frozenset({'Climb', 'Open', 'ChargeJump', 'Grenade'})}, 'L3OuterDoor': {frozenset({'Climb', 'Open', 'ChargeJump', 'Grenade'})}, 'R2OuterDoor': {frozenset({'Climb', 'Open', 'ChargeJump', 'Grenade'})}, 'R3OuterDoor': {frozenset({'Climb', 'Open', 'ChargeJump', 'Grenade'})}}}, 'HoruL4LavaChasePeg': {'casual-core': {'HoruL4CutscenePeg': {frozenset({'Bash', 'Stomp', 'ChargeJump'}), frozenset({'Grenade', 'Bash', 'Stomp'})}}, 'standard-core': {'HoruL4CutscenePeg': {frozenset({'Bash', 'Stomp', 'DoubleJump', 'WallJump'})}}, 'expert-core': {'HoruL4CutscenePeg': {frozenset({'Climb', 'Bash', 'Stomp', 'DoubleJump'})}}, 'expert-abilities': {'HoruL4CutscenePeg': {frozenset({('AC', 6), 'Dash', ('EC', 2), 'Bash', 'Stomp'})}}, 'master-core': {'HoruL4CutscenePeg': {frozenset({'Bash', 'Stomp', 'DoubleJump'})}}}, 'HoruOuterDoor': {'casual-core': {'HoruInnerDoor': {frozenset({'HoruKey'})}, 'HoruFieldsPushBlock': {frozenset({'Grenade', 'Bash'}), frozenset({'Glide', 'Bash'}), frozenset({'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'})}}, 'standard-core': {'HoruFieldsPushBlock': {frozenset({'Dash', 'DoubleJump', 'Bash'})}}, 'standard-abilities': {'HoruFieldsPushBlock': {frozenset({'Climb', 'Dash', 'Glide', 'ChargeJump', ('AC', 3)}), frozenset({'WallJump', 'Dash', 'Glide', 'ChargeJump', ('AC', 3)})}}, 'expert-core': {'HoruFieldsPushBlock': {frozenset({'Glide', 'ChargeJump', 'DoubleJump'})}}, 'expert-abilities': {'HoruFieldsPushBlock': {frozenset({('AC', 6), 'Dash', 'ChargeJump'})}}, 'master-core': {'HoruFieldsPushBlock': {frozenset({'ChargeJump', 'DoubleJump'})}}, 'master-abilities': {'HoruFieldsPushBlock': {frozenset({'Bash', ('AC', 12), 'DoubleJump'})}}, 'gjump': {'HoruFieldsPushBlock': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}}, 'HoruR1CutsceneTrigger': {'glitched': {'LowerGinsoTree': {frozenset({'Dash'})}}}, 'HoruR1MapstoneSecret': {'casual-core': {'HoruR1CutsceneTrigger': {frozenset({'Glide', 'Bash', 'ChargeJump'}), frozenset({'Grenade', 'Bash', 'DoubleJump'}), frozenset({'Bash', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Glide'})}}, 'expert-core': {'HoruR1CutsceneTrigger': {frozenset({'Glide', 'Bash', 'DoubleJump'})}}, 'expert-dboost': {'HoruR1CutsceneTrigger': {frozenset({'Glide', 'ChargeJump', 'DoubleJump', ('HC', 2)}), frozenset({('AC', 6), ('EC', 1), 'Dash', ('HC', 2), 'ChargeJump'})}}, 'dbash': {'HoruR1CutsceneTrigger': {frozenset({'Glide', 'Bash'}), frozenset({'Bash', 'Dash', ('AC', 3)}), frozenset({'Bash', 'DoubleJump'})}}, 'master-core': {'HoruR1CutsceneTrigger': {frozenset({'Bash', 'DoubleJump'})}}, 'master-dboost': {'HoruR1CutsceneTrigger': {frozenset({('HC', 4), ('EC', 4), ('AC', 12), 'Dash', 'DoubleJump'})}}, 'gjump': {'HoruR1CutsceneTrigger': {frozenset({('AC', 12), 'Climb', 'Grenade', 'Glide', 'ChargeJump', ('HC', 1)}), frozenset({'Climb', ('HC', 2), 'Grenade', 'ChargeJump', 'DoubleJump'}), frozenset({'Climb', 'ChargeJump', 'Grenade', ('HC', 6)}), frozenset({('AC', 12), 'Climb', 'Grenade', 'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({'Climb', ('HC', 2), 'Grenade', 'Glide', 'ChargeJump'})}}}, 'HoruR3ElevatorLever': {'casual-core': {'HoruR3CutsceneTrigger': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Glide', 'WallJump'})}}, 'casual-dboost': {'HoruR3CutsceneTrigger': {frozenset({'Climb', ('HC', -1), 'ChargeJump'})}}, 'standard-core': {'HoruR3CutsceneTrigger': {frozenset({'WallJump'})}}, 'master-core': {'HoruR3CutsceneTrigger': {frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'})}}, 'master-abilities': {'HoruR3CutsceneTrigger': {frozenset({('AC', 12), 'DoubleJump'})}, 'HoruR3PlantCove': {frozenset({'Glide', ('AC', 6), 'Dash', ('EC', 1)}), frozenset({('EC', 2), 'Dash', ('AC', 6)}), frozenset({'Dash', ('AC', 6), 'DoubleJump', ('EC', 1)}), frozenset({('AC', 6), 'Dash', 'ChargeJump', ('EC', 1)})}}}, 'HoruR4PuzzleEntrance': {'casual-core': {'HoruR4CutsceneTrigger': {frozenset({'Bash', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}}, 'expert-abilities': {'HoruR4CutsceneTrigger': {frozenset({('AC', 6), 'Dash', 'ChargeJump', ('EC', 2)})}}, 'gjump': {'HoruR4CutsceneTrigger': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}}, 'HoruR4StompHideout': {'casual-core': {'HoruR4PuzzleEntrance': {frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Glide', 'Bash', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb'})}}, 'standard-abilities': {'HoruR4PuzzleEntrance': {frozenset({'Dash', 'ChargeJump', ('AC', 3)}), frozenset({'Bash', 'Dash', ('AC', 3)})}}, 'expert-dboost': {'HoruR4PuzzleEntrance': {frozenset({'ChargeJump', ('HC', 2)}), frozenset({'Bash', ('HC', 2)})}, 'HoruR4CutsceneTrigger': {frozenset({'ChargeJump', 'DoubleJump', ('HC', 2)})}}, 'dbash': {'HoruR4PuzzleEntrance': {frozenset({'Bash'})}, 'HoruR4CutsceneTrigger': {frozenset({'Bash'})}}, 'master-dboost': {'HoruR4PuzzleEntrance': {frozenset({('AC', 12), 'DoubleJump', ('HC', 1)})}}, 'gjump': {'HoruR4PuzzleEntrance': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'expert-core': {'HoruR4CutsceneTrigger': {frozenset({'Bash', 'ChargeJump'})}}}, 'HoruTeleporter': {'casual-core': {'HoruInnerDoor': {frozenset({'Climb', 'Open', 'ChargeJump'}), frozenset({'Open', 'ChargeJump', 'WallJump'}), frozenset({'Grenade', 'Open', 'Bash'})}}, 'dbash': {'HoruInnerDoor': {frozenset({'Open', 'Bash'})}}, 'master-core': {'HoruInnerDoor': {frozenset({'Open', 'ChargeJump', 'DoubleJump'})}}, 'master-abilities': {'HoruInnerDoor': {frozenset({'Open', ('AC', 12), 'DoubleJump', 'WallJump'})}}}, 'Iceless': {'casual-core': {'UpperGrotto': {frozenset({'DoubleJump'}), frozenset({'Glide'})}}, 'standard-core': {'UpperGrotto': {frozenset({'Grenade', 'Bash'})}}, 'standard-dboost': {'UpperGrotto': {frozenset({('HC', 1)})}}, 'gjump': {'UpperGrotto': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}}, 'InnerSwampAboveDrainArea': {'casual-core': {'InnerSwampDrainBroken': {frozenset({'ChargeFlame', 'Water'}), frozenset({'Grenade'})}}, 'casual-dboost': {'InnerSwampDrainBroken': {frozenset({'ChargeFlame'})}}}, 'InnerSwampDrainBroken': {'casual-core': {'Swamp': {frozenset({'Climb', 'ChargeJump', 'Water'}), frozenset({'Climb', 'Bash', 'Grenade', 'Water'}), frozenset({'Glide', 'ChargeJump', 'WallJump'}), frozenset({'DoubleJump', 'WallJump', 'Water'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Climb', 'Glide', 'ChargeJump'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'WallJump', 'Water'})}}, 'casual-dboost': {'Swamp': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'Water'}), frozenset({'Climb', 'ChargeJump'})}}, 'expert-core': {'Swamp': {frozenset({'DoubleJump', 'Water'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump'})}}, 'expert-dboost': {'Swamp': {frozenset({'ChargeJump'}), frozenset({'Climb', ('HC', 0), 'Water'})}}, 'master-core': {'Swamp': {frozenset({'Bash'})}}, 'standard-core': {'Swamp': {frozenset({'Climb', 'DoubleJump', 'Water'})}}, 'standard-abilities': {'Swamp': {frozenset({'Climb', 'Dash', ('AC', 3), 'Water'}), frozenset({'Dash', ('AC', 3), 'WallJump', 'Water'})}}, 'master-dboost': {'Swamp': {frozenset({('HC', 10), 'WallJump'}), frozenset({'Climb', ('HC', 4), ('AC', 12)}), frozenset({'Climb', ('HC', 10)}), frozenset({('HC', 10), 'DoubleJump'}), frozenset({('HC', 4), ('AC', 12), 'DoubleJump'}), frozenset({('HC', 4), ('AC', 12), 'WallJump'})}}}, 'L2OuterDoor': {'casual-core': {'HoruInnerDoor': {frozenset({'Stomp'})}}}, 'L3OuterDoor': {'casual-core': {'HoruInnerDoor': {frozenset({'Stomp'})}}}, 'L4': {'casual-core': {'HoruL4LavaChasePeg': {frozenset({'Bash'})}}, 'expert-core': {'HoruL4CutscenePeg': {frozenset({'Free'})}}}, 'LeftGlades': {'casual-core': {'UpperLeftGlades': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}}, 'standard-lure': {'UpperLeftGlades': {frozenset({'Bash'})}}, 'expert-core': {'UpperLeftGlades': {frozenset({'DoubleJump'})}}}, 'LeftGumoHideout': {'casual-core': {'WaterVeinArea': {frozenset({'Glide', 'Wind'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'WallJump'})}}, 'standard-core': {'WaterVeinArea': {frozenset({'Climb', 'DoubleJump'})}}, 'standard-abilities': {'WaterVeinArea': {frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}}, 'master-core': {'WaterVeinArea': {frozenset({'Dash', 'WallJump'}), frozenset({'DoubleJump'})}}}, 'LeftSorrow': {'casual-core': {'LeftSorrowKeystones': {frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Glide'})}}, 'expert-dboost': {'LeftSorrowKeystones': {frozenset({'ChargeJump', 'WallJump', ('HC', 2)})}}, 'master-dboost': {'LeftSorrowKeystones': {frozenset({('AC', 12), 'ChargeJump', 'WallJump', ('HC', 1)})}}, 'master-abilities': {'LeftSorrowKeystones': {frozenset({'Climb', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}}, 'master-core': {'LeftSorrowKeystones': {frozenset({'Bash'})}}}, 'LeftSorrowKeystones': {'casual-core': {'LeftSorrowMiddleDoor': {frozenset({('KS', 4)})}}, 'standard-core': {'MiddleSorrow': {frozenset({'Bash', 'Dash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'Dash', 'DoubleJump'})}}, 'expert-abilities': {'MiddleSorrow': {frozenset({'Bash', ('AC', 6), 'Dash', 'WallJump'}), frozenset({'Climb', 'Bash', ('AC', 6), 'Dash'})}}, 'dbash': {'MiddleSorrow': {frozenset({'Bash'})}}, 'master-abilities': {'MiddleSorrow': {frozenset({'ChargeJump', ('AC', 12), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Dash', 'Stomp', 'ChargeJump', ('AC', 3)}), frozenset({('AC', 12), 'Climb', 'Stomp', 'ChargeJump', 'DoubleJump'}), frozenset({('AC', 6), 'Dash', 'Stomp', 'ChargeJump', 'WallJump'})}}}, 'LeftSorrowLowerDoor': {'casual-core': {'LeftSorrow': {frozenset({'Glide', 'Stomp', 'Bash'})}}, 'standard-core': {'LeftSorrow': {frozenset({'Climb', 'Bash', 'ChargeJump', 'Stomp'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({'Bash', 'ChargeJump', 'Stomp', 'WallJump'})}}, 'expert-dboost': {'LeftSorrow': {frozenset({'Climb', 'ChargeJump', ('HC', 2)})}}, 'dbash': {'LeftSorrow': {frozenset({'Bash', 'Stomp', ('HC', 2)}), frozenset({'Grenade', 'Bash', 'Stomp'}), frozenset({'Bash', 'Stomp', 'DoubleJump'})}}}, 'LeftSorrowMiddleDoor': {'casual-core': {'MiddleSorrow': {frozenset({'Bash', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'Stomp', 'Bash'}), frozenset({'Climb', 'Bash', 'Stomp', 'DoubleJump'}), frozenset({'Glide', 'Stomp', 'WallJump', 'Bash'})}}, 'standard-core': {'MiddleSorrow': {frozenset({'Climb', 'Bash', 'Stomp'}), frozenset({'Bash', 'Stomp', 'WallJump'}), frozenset({'Bash', 'Stomp', 'DoubleJump'})}}, 'expert-dboost': {'MiddleSorrow': {frozenset({'Climb', ('HC', 2), 'Bash', 'ChargeJump', 'DoubleJump'})}}, 'master-abilities': {'MiddleSorrow': {frozenset({('AC', 6), 'Climb', 'Dash', 'Bash', 'ChargeJump'}), frozenset({('AC', 6), 'Bash', 'Stomp', 'Dash'})}}, 'master-dboost': {'MiddleSorrow': {frozenset({('AC', 12), 'Climb', 'Bash', 'ChargeJump', 'DoubleJump', ('HC', 1)})}}, 'glitched': {'MiddleSorrow': {frozenset({'Dash'})}}}, 'LostGrove': {'casual-core': {'LostGroveExit': {frozenset({'Grenade', 'Bash', 'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'DoubleJump', 'WallJump'})}}, 'casual-dboost': {'LostGroveExit': {frozenset({'Grenade', 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump', 'DoubleJump'})}}, 'expert-core': {'LostGroveExit': {frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Grenade', 'Glide', 'Climb', 'ChargeJump'}), frozenset({'Grenade', 'Bash', 'WallJump'})}}, 'expert-dboost': {'LostGroveExit': {frozenset({'Grenade', ('HC', 4), 'ChargeJump', 'WallJump'}), frozenset({'Grenade', 'Dash', 'ChargeJump', 'WallJump'}), frozenset({'Grenade', 'Climb', 'ChargeJump', ('HC', 4)}), frozenset({'Grenade', 'Glide', 'ChargeJump', 'WallJump'})}}, 'expert-abilities': {'LostGroveExit': {frozenset({'Climb', 'Dash', 'Grenade', 'ChargeJump', ('AC', 3)})}}, 'master-abilities': {'LostGroveExit': {frozenset({'Grenade', 'Climb', ('AC', 12), 'DoubleJump'}), frozenset({'Grenade', ('AC', 12), 'DoubleJump', 'WallJump'})}}, 'gjump': {'LostGroveExit': {frozenset({'Grenade', 'Climb', 'ChargeJump'})}}}, 'LowerBlackroot': {'casual-core': {'LostGrove': {frozenset({'Grenade', 'ChargeJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'Grenade'})}}, 'expert-core': {'LostGrove': {frozenset({'Grenade', 'DoubleJump'})}}}, 'LowerChargeFlameArea': {'casual-core': {'GladesMain': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'ChargeFlameAreaStump': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}}, 'standard-core': {'GladesMain': {frozenset({'Stomp'})}}, 'expert-abilities': {'GladesMain': {frozenset({'Dash', ('AC', 6)})}}, 'master-core': {'ChargeFlameAreaStump': {frozenset({'DoubleJump'})}}, 'master-lure': {'ChargeFlameAreaStump': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'Bash', ('AC', 6), 'Dash'}), frozenset({'Bash', 'Stomp'})}}}, 'LowerGinsoTree': {'casual-core': {'GinsoMiniBossDoor': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Climb', 'Glide'}), frozenset({'Grenade', 'Bash', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Glide'}), frozenset({'Glide', 'WallJump'})}}, 'standard-dboost': {'GinsoMiniBossDoor': {frozenset({'Climb', ('HC', 0)}), frozenset({('HC', 0), 'WallJump'}), frozenset({'ChargeJump', ('HC', 0)})}}, 'standard-abilities': {'GinsoMiniBossDoor': {frozenset({'Dash', 'ChargeJump', ('AC', 3)}), frozenset({'Dash', ('AC', 3), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 3)})}}, 'expert-core': {'GinsoMiniBossDoor': {frozenset({'WallJump'})}}, 'master-core': {'GinsoMiniBossDoor': {frozenset({'DoubleJump'}), frozenset({'Bash'})}}, 'glitched': {'R4InnerDoor': {frozenset({'Dash'})}}}, 'LowerLeftGumoHideout': {'glitched': {'LowerBlackroot': {frozenset({'Dash'})}}}, 'LowerSorrow': {'casual-core': {'WilhelmLedge': {frozenset({'Glide', 'DoubleJump'})}, 'SorrowMainShaftKeystoneArea': {frozenset({'Glide'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'Bash'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'Bash', 'WallJump'})}, 'SorrowMapstoneArea': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'}), frozenset({'Climb', 'ChargeJump'})}, 'LeftSorrowLowerDoor': {frozenset({('KS', 4)})}, 'LeftSorrow': {frozenset({'Glide', 'Bash'}), frozenset({'Glide', 'ChargeJump'})}, 'MiddleSorrow': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-core': {'WilhelmLedge': {frozenset({'Glide', 'Dash'}), frozenset({'Dash', 'DoubleJump'})}, 'MiddleSorrow': {frozenset({'Glide', 'Bash'})}}, 'expert-dboost': {'WilhelmLedge': {frozenset({'Glide', ('HC', 2)}), frozenset({'DoubleJump', ('HC', 2)})}}, 'expert-abilities': {'WilhelmLedge': {frozenset({'Dash', ('AC', 6), 'Bash'}), frozenset({('EC', 2), 'Dash', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'Stomp'})}, 'SorrowMainShaftKeystoneArea': {frozenset({'Dash', ('AC', 6)})}, 'LeftSorrow': {frozenset({'Dash', ('AC', 6), 'Bash'}), frozenset({('AC', 6), 'Dash', 'Stomp', 'ChargeJump'}), frozenset({('AC', 6), 'Dash', 'ChargeJump', 'DoubleJump'}), frozenset({('EC', 2), 'Dash', 'ChargeJump', ('AC', 6)})}, 'MiddleSorrow': {frozenset({'Dash', ('AC', 6)})}}, 'dbash': {'WilhelmLedge': {frozenset({'Bash'})}, 'SorrowMainShaftKeystoneArea': {frozenset({'Bash'})}, 'SorrowMapstoneArea': {frozenset({'Bash'})}, 'LeftSorrow': {frozenset({'Bash'})}, 'SunstoneArea': {frozenset({'Glide', 'Bash'})}}, 'master-dboost': {'WilhelmLedge': {frozenset({'Glide', ('AC', 12), ('HC', 1)})}, 'LeftSorrow': {frozenset({('AC', 12), 'ChargeJump', ('HC', 7)})}}, 'master-abilities': {'WilhelmLedge': {frozenset({('AC', 12), 'DoubleJump'})}, 'LeftSorrow': {frozenset({('AC', 12), 'ChargeJump', 'DoubleJump'})}}, 'standard-lure': {'SorrowMapstoneArea': {frozenset({'Climb', 'Glide'}), frozenset({'Glide', 'WallJump'})}}, 'gjump': {'LeftSorrow': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'master-core': {'MiddleSorrow': {frozenset({'Bash'})}}, 'glitched': {'MiddleSorrow': {frozenset({'Glide', 'ChargeJump'})}}}, 'LowerSpiritCaverns': {'casual-core': {'MidSpiritCaverns': {frozenset({'Grenade', 'Bash'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'})}, 'GladesLaserArea': {frozenset({'Bash', ('EC', 4)})}, 'SpiritCavernsDoor': {frozenset({'Open'})}}, 'expert-core': {'MidSpiritCaverns': {frozenset({'Bash', 'Dash'})}}, 'dbash': {'MidSpiritCaverns': {frozenset({'Bash'})}}, 'master-core': {'MidSpiritCaverns': {frozenset({'DoubleJump'})}}}, 'LowerValley': {'casual-core': {'LowerValleyPlantApproach': {frozenset({'Glide', 'Wind'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash'}), frozenset({'Glide', 'ChargeJump'})}, 'ValleyThreeBirdLever': {frozenset({'Glide', 'Wind'}), frozenset({'Glide', 'DoubleJump'})}, 'MistyEntrance': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Glide', 'Wind'})}, 'ValleyTeleporter': {frozenset({'Glide', 'OpenWorld', 'Wind'}), frozenset({'Climb', 'Glide', 'ChargeJump', 'OpenWorld'}), frozenset({'Climb', 'Bash', 'ChargeJump', 'OpenWorld'}), frozenset({'Climb', 'OpenWorld', 'ChargeJump', 'DoubleJump'})}}, 'standard-lure': {'LowerValleyPlantApproach': {frozenset({'Bash'})}, 'ValleyThreeBirdLever': {frozenset({'Glide', 'Bash'}), frozenset({'Bash', 'DoubleJump'})}}, 'standard-core': {'ValleyThreeBirdLever': {frozenset({'Glide', 'Dash'}), frozenset({'Dash', 'DoubleJump'})}, 'MistyEntrance': {frozenset({'Climb', 'Bash', 'Grenade'})}, 'ValleyTeleporter': {frozenset({'Climb', 'Bash', 'Grenade', 'OpenWorld'}), frozenset({'OpenWorld', 'Grenade', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({'OpenWorld', 'ChargeJump', 'DoubleJump', 'WallJump'})}}, 'standard-dboost': {'ValleyThreeBirdLever': {frozenset({('HC', 1)})}}, 'expert-dboost': {'ValleyThreeBirdLever': {frozenset({('HC', -1)})}}, 'dbash': {'ValleyThreeBirdLever': {frozenset({'Bash'})}, 'MistyEntrance': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}}, 'expert-abilities': {'MistyEntrance': {frozenset({'Dash', ('AC', 6)})}, 'ValleyTeleporter': {frozenset({'Dash', ('AC', 6), 'OpenWorld'})}}, 'master-lure': {'MistyEntrance': {frozenset({'Bash'})}, 'ValleyTeleporter': {frozenset({'Bash', 'OpenWorld'})}}}, 'MidSpiritCaverns': {'casual-core': {'GladesLaserArea': {frozenset({('EC', 4)})}, 'UpperSpiritCaverns': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}}, 'glitched': {'GladesLaserArea': {frozenset({('EC', 3)})}}, 'casual-dboost': {'UpperSpiritCaverns': {frozenset({'DoubleJump'})}}, 'standard-core': {'UpperSpiritCaverns': {frozenset({'Bash'})}}}, 'MiddleSorrow': {'casual-core': {'UpperSorrow': {frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Glide'})}, 'SorrowMainShaftKeystoneArea': {frozenset({'Stomp'})}, 'LowerSorrow': {frozenset({'Stomp'})}}, 'gjump': {'UpperSorrow': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'expert-dboost': {'UpperSorrow': {frozenset({'ChargeJump', 'WallJump', ('HC', 2)}), frozenset({'Climb', 'ChargeJump', ('HC', 2)})}}, 'master-dboost': {'UpperSorrow': {frozenset({('AC', 12), 'ChargeJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', ('AC', 12), 'ChargeJump', ('HC', 1)})}}, 'expert-abilities': {'LeftSorrow': {frozenset({'Climb', 'Dash', 'Stomp', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'Stomp', 'WallJump'})}, 'LeftSorrowKeystones': {frozenset({'Climb', 'Dash', 'Stomp', ('AC', 6)}), frozenset({('AC', 6), 'Dash', 'Stomp', 'WallJump'})}, 'SorrowMainShaftKeystoneArea': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}, 'LowerSorrow': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'standard-core': {'SorrowMainShaftKeystoneArea': {frozenset({'Climb', 'ChargeJump'})}, 'LowerSorrow': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-core': {'SorrowMainShaftKeystoneArea': {frozenset({'Grenade', 'Bash', 'ChargeJump'})}, 'LowerSorrow': {frozenset({'Grenade', 'Bash', 'ChargeJump'})}, 'SunstoneArea': {frozenset({'Glide', 'Bash'})}}}, 'MistyAbove200xp': {'casual-core': {'MistyBeforeMiniBoss': {frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Glide'})}}, 'standard-core': {'MistyBeforeMiniBoss': {frozenset({'Grenade', 'Bash'}), frozenset({'Dash', 'DoubleJump'})}}, 'standard-abilities': {'MistyBeforeMiniBoss': {frozenset({('AC', 12), 'DoubleJump'}), frozenset({'Dash', ('AC', 6)})}}, 'master-core': {'MistyBeforeMiniBoss': {frozenset({'Bash'})}}}, 'MistyBeforeDocks': {'casual-core': {'MistyAbove200xp': {frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'Climb', 'DoubleJump'})}}, 'standard-core': {'MistyAbove200xp': {frozenset({'Glide', 'ChargeJump'})}}, 'standard-abilities': {'MistyAbove200xp': {frozenset({'Bash', ('AC', 6), 'Dash'}), frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'expert-abilities': {'MistyAbove200xp': {frozenset({'Dash', ('AC', 6)})}}, 'master-core': {'MistyAbove200xp': {frozenset({'Bash'})}}}, 'MistyBeforeMiniBoss': {'casual-core': {'MistyOrbRoom': {frozenset({('KS', 4)})}}}, 'MistyEntrance': {'casual-core': {'MistyPostFeatherTutorial': {frozenset({'Glide', 'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'WallJump'}), frozenset({'Glide', 'Bash', 'Climb'})}}, 'standard-core': {'MistyPostFeatherTutorial': {frozenset({'Glide', 'Bash'})}}, 'standard-abilities': {'MistyPostFeatherTutorial': {frozenset({'Climb', 'Dash', 'Glide', 'ChargeJump', 'DoubleJump', ('AC', 3)}), frozenset({'Dash', 'Glide', ('AC', 3), 'ChargeJump', 'DoubleJump', 'WallJump'})}}, 'expert-core': {'MistyPostFeatherTutorial': {frozenset({'Climb', 'Glide', 'ChargeJump', 'DoubleJump'})}}, 'expert-dboost': {'MistyPostFeatherTutorial': {frozenset({('HC', 4), 'ChargeJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump', ('HC', 1)})}}, 'expert-abilities': {'MistyPostFeatherTutorial': {frozenset({'Dash', ('AC', 6), ('EC', 4)}), frozenset({'Dash', 'Glide', 'ChargeJump', 'DoubleJump', ('AC', 3)})}}, 'master-core': {'MistyPostFeatherTutorial': {frozenset({'Bash'})}}, 'gjump': {'MistyPostFeatherTutorial': {frozenset({'Climb', 'ChargeJump', 'Grenade', ('HC', 1)})}}}, 'MistyKeystone3Ledge': {'casual-core': {'MistyPreLasers': {frozenset({'Glide'})}}, 'standard-abilities': {'MistyPreLasers': {frozenset({('AC', 12), 'DoubleJump'}), frozenset({'Dash', ('AC', 6)})}}, 'expert-core': {'MistyPreLasers': {frozenset({'Grenade', 'Bash'}), frozenset({'Dash', 'DoubleJump'})}}, 'expert-dboost': {'MistyPreLasers': {frozenset({'ChargeJump', ('HC', 1)}), frozenset({'DoubleJump', ('HC', 1)})}}, 'master-dboost': {'MistyPreLasers': {frozenset({('HC', 4), 'WallJump'})}}, 'gjump': {'MistyPreLasers': {frozenset({'Grenade', 'Climb', 'ChargeJump'})}}}, 'MistyKeystone4Ledge': {'casual-core': {'MistyBeforeDocks': {frozenset({'Glide', 'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump', 'Glide'}), frozenset({'Climb', 'Bash', 'Glide', 'DoubleJump'})}}, 'standard-core': {'MistyBeforeDocks': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'})}}, 'master-abilities': {'MistyBeforeDocks': {frozenset({'Dash', ('AC', 6)})}}, 'master-dboost': {'MistyBeforeDocks': {frozenset({'ChargeJump', 'DoubleJump', ('HC', 7)})}}, 'master-lure': {'MistyBeforeDocks': {frozenset({'Bash'})}}}, 'MistyMortarSpikeCave': {'casual-core': {'MistyKeystone4Ledge': {frozenset({'Glide', 'Bash', 'WallJump'}), frozenset({'Climb', 'Bash', 'Glide'})}}, 'standard-core': {'MistyKeystone4Ledge': {frozenset({'Glide', 'Bash', 'DoubleJump'})}}, 'expert-core': {'MistyKeystone4Ledge': {frozenset({'Glide', 'Bash'})}}, 'expert-abilities': {'MistyKeystone4Ledge': {frozenset({'Bash', ('AC', 6), 'Dash'})}}, 'master-core': {'MistyKeystone4Ledge': {frozenset({'Bash'})}}, 'master-abilities': {'MistyKeystone4Ledge': {frozenset({'Dash', ('AC', 6)}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump'})}}}, 'MistyOrbRoom': {'casual-core': {'MistyPreKeystone2': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}}, 'master-core': {'MistyPreKeystone2': {frozenset({'DoubleJump'})}}}, 'MistyPostClimb': {'casual-core': {'MistySpikeCave': {frozenset({'Climb', 'DoubleJump', 'WallJump'})}}, 'standard-core': {'MistySpikeCave': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-core': {'MistySpikeCave': {frozenset({'ChargeJump'})}}, 'expert-abilities': {'MistySpikeCave': {frozenset({'Bash', ('AC', 6), 'Dash'})}}, 'dbash': {'MistySpikeCave': {frozenset({'Bash'})}}, 'master-core': {'MistySpikeCave': {frozenset({'DoubleJump'})}}}, 'MistyPostFeatherTutorial': {'casual-core': {'MistyPostKeystone1': {frozenset({'Free'})}}}, 'MistyPostKeystone1': {'casual-core': {'MistyPreMortarCorridor': {frozenset({'Glide', 'Bash'})}}, 'expert-core': {'MistyPreMortarCorridor': {frozenset({'Glide'})}}, 'expert-dboost': {'MistyPreMortarCorridor': {frozenset({('HC', 6)}), frozenset({'Dash', ('AC', 3), ('HC', 1)}), frozenset({'DoubleJump', ('HC', 1)})}}, 'master-core': {'MistyPreMortarCorridor': {frozenset({'Bash'})}}, 'master-abilities': {'MistyPreMortarCorridor': {frozenset({'Dash', ('AC', 6), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump'})}}, 'master-dboost': {'MistyPreMortarCorridor': {frozenset({('HC', 3)}), frozenset({('AC', 12), ('HC', 1)})}}}, 'MistyPostLasers': {'casual-core': {'MistyMortarSpikeCave': {frozenset({'Glide', 'Bash', 'DoubleJump'})}}, 'standard-core': {'MistyMortarSpikeCave': {frozenset({'Glide', 'Bash'})}}, 'expert-core': {'MistyMortarSpikeCave': {frozenset({'Glide'})}}, 'master-core': {'MistyMortarSpikeCave': {frozenset({'Bash'})}}}, 'MistyPostMortarCorridor': {'casual-core': {'MistyPrePlantLedge': {frozenset({'Bash'})}}, 'standard-core': {'MistyPrePlantLedge': {frozenset({'ChargeJump', 'WallJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Climb', 'ChargeJump'})}}, 'master-core': {'MistyPrePlantLedge': {frozenset({'DoubleJump'})}}, 'master-abilities': {'MistyPrePlantLedge': {frozenset({'Dash', ('AC', 6)})}}}, 'MistyPreClimb': {'casual-core': {'MistyPostClimb': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'Stomp', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Stomp'})}}, 'expert-core': {'MistyPostClimb': {frozenset({'Grenade', 'Bash', 'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'DoubleJump', 'WallJump'})}}, 'master-core': {'MistyPostClimb': {frozenset({'Stomp', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'DoubleJump'})}}, 'glitched': {'ForlornTeleporter': {frozenset({'Dash'})}, 'RightForlorn': {frozenset({'Dash'})}}}, 'MistyPreLasers': {'casual-core': {'MistyPostLasers': {frozenset({'Climb', 'Glide', 'WallJump'})}}, 'standard-core': {'MistyPostLasers': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump'})}}, 'expert-core': {'MistyPostLasers': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Dash', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}}, 'master-core': {'MistyPostLasers': {frozenset({'DoubleJump'}), frozenset({'Bash'})}}}, 'MistyPreMortarCorridor': {'casual-core': {'MistyPostMortarCorridor': {frozenset({'Glide'})}}, 'expert-dboost': {'MistyPostMortarCorridor': {frozenset({'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({'Dash', 'DoubleJump', ('AC', 3), ('HC', 1)})}}, 'master-core': {'MistyPostMortarCorridor': {frozenset({'Grenade', 'Bash', 'DoubleJump'})}}, 'master-abilities': {'MistyPostMortarCorridor': {frozenset({'Dash', ('AC', 6)})}}, 'master-dboost': {'MistyPostMortarCorridor': {frozenset({('AC', 12), ('HC', 6)}), frozenset({('HC', 7)})}}, 'glitched': {'RightForlorn': {frozenset({'Free'})}}}, 'MistyPrePlantLedge': {'casual-core': {'MistyPreClimb': {frozenset({'ChargeJump'}), frozenset({'Glide', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'DoubleJump'})}}, 'standard-core': {'MistyPreClimb': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'})}}, 'expert-core': {'MistyPreClimb': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'WallJump'})}}, 'master-core': {'MistyPreClimb': {frozenset({'DoubleJump'}), frozenset({'Bash'})}}}, 'MistySpikeCave': {'casual-core': {'MistyKeystone3Ledge': {frozenset({'Climb', 'DoubleJump', 'WallJump'})}}, 'standard-core': {'MistyKeystone3Ledge': {frozenset({'Glide', 'Bash', 'DoubleJump'})}}, 'expert-core': {'MistyKeystone3Ledge': {frozenset({'DoubleJump'})}}, 'master-core': {'MistyKeystone3Ledge': {frozenset({'Bash'})}}, 'master-dboost': {'MistyKeystone3Ledge': {frozenset({'ChargeJump', ('HC', 1)})}}}, 'MoonGrotto': {'casual-core': {'MoonGrottoAboveTeleporter': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'DeathGauntlet': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'WaterVeinArea': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'})}, 'MoonGrottoBelowTeleporter': {frozenset({'DoubleJump'}), frozenset({'Glide', 'ChargeJump'})}}, 'master-core': {'MoonGrottoAboveTeleporter': {frozenset({'DoubleJump'})}}, 'expert-abilities': {'MoonGrottoAboveTeleporter': {frozenset({'Dash', ('AC', 6), ('EC', 1)})}}, 'standard-core': {'WaterVeinArea': {frozenset({'Dash'})}}, 'expert-core': {'WaterVeinArea': {frozenset({'WallJump'})}}, 'master-lure': {'WaterVeinArea': {frozenset({'Bash'})}}, 'standard-dboost': {'MoonGrottoBelowTeleporter': {frozenset({'Glide', ('HC', 1)})}}, 'standard-abilities': {'MoonGrottoBelowTeleporter': {frozenset({'Dash', ('AC', 3)})}}}, 'MoonGrottoAboveTeleporter': {'casual-core': {'UpperGrotto': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'WallJump'})}, 'MoonGrottoSwampAccessArea': {frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Bash'})}}, 'standard-core': {'UpperGrotto': {frozenset({'Grenade', 'Bash'})}}, 'expert-core': {'UpperGrotto': {frozenset({'Climb', 'Glide'})}, 'MoonGrottoStompPlantAccess': {frozenset({'ChargeFlame'})}}, 'master-core': {'UpperGrotto': {frozenset({'DoubleJump'}), frozenset({'Bash', 'Dash', ('AC', 3)})}}, 'casual-dboost': {'MoonGrottoSwampAccessArea': {frozenset({'DoubleJump'})}}, 'standard-dboost': {'MoonGrottoSwampAccessArea': {frozenset({'ChargeJump', ('HC', 0)})}}, 'expert-dboost': {'MoonGrottoSwampAccessArea': {frozenset({'Dash', ('HC', 1)})}}, 'expert-abilities': {'MoonGrottoSwampAccessArea': {frozenset({'Dash', ('AC', 6)})}}, 'gjump': {'MoonGrottoSwampAccessArea': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'master-lure': {'DeathGauntletRoof': {frozenset({'Bash'})}, 'MoonGrottoBelowTeleporter': {frozenset({'Bash'})}}}, 'MoonGrottoSwampAccessArea': {'casual-core': {'InnerSwampAboveDrainArea': {frozenset({'ChargeJump'})}}, 'standard-lure': {'InnerSwampAboveDrainArea': {frozenset({'Bash'})}}, 'expert-lure': {'InnerSwampAboveDrainArea': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Stomp', 'DoubleJump'}), frozenset({'Climb', 'ChargeFlame'})}}, 'master-lure': {'InnerSwampAboveDrainArea': {frozenset({'Grenade', 'DoubleJump'})}}}, 'OuterSwampAbilityCellNook': {'glitched': {'InnerSwampSkyArea': {frozenset({'Dash'})}}}, 'OuterSwampLowerArea': {'casual-core': {'OuterSwampMortarAbilityCellLedge': {frozenset({'Bash'})}, 'OuterSwampUpperArea': {frozenset({'Glide', 'Wind'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'ChargeJump'}), frozenset({'Climb', 'DoubleJump'})}, 'OuterSwampAbilityCellNook': {frozenset({'Glide', 'Wind'}), frozenset({'Grenade', 'Bash'})}, 'OuterSwampMortarPlantAccess': {frozenset({'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Bash'})}, 'SwampEntryArea': {frozenset({'Glide', 'Wind'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}, 'UpperGrotto': {frozenset({'Glide', 'Wind'}), frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'Bash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}}, 'expert-abilities': {'OuterSwampMortarAbilityCellLedge': {frozenset({'Dash', ('AC', 6)})}, 'OuterSwampUpperArea': {frozenset({'Dash', ('AC', 6)})}}, 'master-abilities': {'OuterSwampMortarAbilityCellLedge': {frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}}, 'expert-core': {'OuterSwampUpperArea': {frozenset({'Climb'}), frozenset({'WallJump'})}}, 'standard-core': {'OuterSwampAbilityCellNook': {frozenset({'Climb'}), frozenset({'Bash'}), frozenset({'WallJump'})}}}, 'OuterSwampMortarAbilityCellLedge': {'expert-core': {'OuterSwampMortarPlantAccess': {frozenset({'ChargeFlame'})}}}, 'OuterSwampUpperArea': {'casual-core': {'GinsoOuterDoor': {frozenset({'GinsoKey'})}, 'OuterSwampAbilityCellNook': {frozenset({'DoubleJump'}), frozenset({'Glide'})}}, 'standard-core': {'OuterSwampAbilityCellNook': {frozenset({'Free'})}}}, 'OutsideForlorn': {'casual-core': {'OutsideForlornCliff': {frozenset({'Grenade', 'Bash'}), frozenset({'Bash', 'DoubleJump'}), frozenset({'Glide', 'Bash'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'WallJump'})}, 'ForlornOuterDoor': {frozenset({'ForlornKey'})}}, 'expert-abilities': {'OutsideForlornCliff': {frozenset({'Dash', ('AC', 6)})}}, 'dbash': {'OutsideForlornCliff': {frozenset({'Bash'})}}, 'master-core': {'OutsideForlornCliff': {frozenset({'ChargeJump', 'DoubleJump'})}}, 'glitched': {'RightForlorn': {frozenset({'Free'})}}}, 'OutsideForlornCliff': {'casual-core': {'ValleyForlornApproach': {frozenset({'Stomp', 'ChargeJump', 'Bash'}), frozenset({'Climb', 'Stomp', 'DoubleJump', 'Bash'}), frozenset({'Stomp', 'WallJump', 'Bash'}), frozenset({'Grenade', 'Stomp', 'Bash'})}}, 'expert-core': {'ValleyForlornApproach': {frozenset({'ChargeFlame', 'Stomp', 'WallJump'}), frozenset({'ChargeFlame', 'Stomp', 'Climb', 'DoubleJump'}), frozenset({'ChargeFlame', 'Stomp', 'ChargeJump'})}}, 'master-core': {'ValleyForlornApproach': {frozenset({'Bash'})}}}, 'R1': {'casual-core': {'HoruR1MapstoneSecret': {frozenset({'DoubleJump'}), frozenset({'Glide'})}}, 'standard-core': {'HoruR1MapstoneSecret': {frozenset({'Grenade', 'Bash'})}}, 'standard-abilities': {'HoruR1MapstoneSecret': {frozenset({'Dash', ('AC', 3)})}}, 'expert-dboost': {'HoruR1MapstoneSecret': {frozenset({'Climb', 'ChargeJump', ('HC', 2)}), frozenset({'Bash', ('HC', 2)}), frozenset({'Dash', ('HC', 2)})}}, 'master-dboost': {'HoruR1MapstoneSecret': {frozenset({'Dash', ('AC', 12), ('HC', 1)}), frozenset({('HC', 6)}), frozenset({'Climb', ('AC', 12), 'ChargeJump', ('HC', 1)}), frozenset({'Bash', ('AC', 12), ('HC', 1)}), frozenset({('HC', 4), ('AC', 12)})}}, 'gjump': {'HoruR1MapstoneSecret': {frozenset({('AC', 12), 'Climb', 'Grenade', 'ChargeJump', ('HC', 1)}), frozenset({'Climb', 'ChargeJump', 'Grenade', ('HC', 2)}), frozenset({'Climb', 'Stomp', 'ChargeJump', 'Grenade'})}}}, 'R1OuterDoor': {'expert-core': {'L1OuterDoor': {frozenset({'Free'})}}}, 'R3': {'casual-core': {'HoruR3ElevatorLever': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Bash', 'Climb'})}}, 'expert-core': {'HoruR3ElevatorLever': {frozenset({'Grenade', 'Bash', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'WallJump'})}}, 'master-abilities': {'HoruR3ElevatorLever': {frozenset({'Climb', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'ChargeJump', 'DoubleJump'})}}}, 'R3OuterDoor': {'casual-core': {'HoruInnerDoor': {frozenset({'Stomp'})}}}, 'R4': {'casual-core': {'HoruR4StompHideout': {frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Grenade', 'Stomp', 'Bash'}), frozenset({'Grenade', 'Bash', 'WallJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'ChargeFlame', 'Bash', 'Grenade'}), frozenset({'Stomp', 'ChargeJump'})}}, 'standard-core': {'HoruR4StompHideout': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}}, 'expert-core': {'HoruR4StompHideout': {frozenset({'ChargeFlame', 'Bash'}), frozenset({'Bash', 'Stomp'})}}, 'expert-abilities': {'HoruR4StompHideout': {frozenset({'Bash', ('AC', 6), 'Dash'})}}, 'expert-dboost': {'HoruR4StompHideout': {frozenset({('HC', 3), 'Bash'})}}, 'dbash': {'HoruR4StompHideout': {frozenset({'Bash'})}}}, 'RazielNoArea': {'casual-core': {'BlackrootGrottoConnection': {frozenset({'Grenade', 'Dash', 'Bash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Dash', 'ChargeJump'}), frozenset({'Climb', 'Dash', 'DoubleJump'})}}, 'standard-core': {'BlackrootGrottoConnection': {frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'WallJump'}), frozenset({'Grenade', 'Bash'})}}, 'expert-core': {'BlackrootGrottoConnection': {frozenset({'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'WallJump'})}}, 'expert-dboost': {'BlackrootGrottoConnection': {frozenset({'Climb', 'Dash', ('AC', 3)})}}, 'glitched': {'BlackrootGrottoConnection': {frozenset({'Climb'})}, 'GumoHideout': {frozenset({'Grenade', 'Dash', 'Bash'}), frozenset({'Dash', 'WallJump'}), frozenset({'Dash', 'ChargeJump'}), frozenset({'Climb', 'Dash', 'DoubleJump'})}}}, 'SorrowBashLedge': {'casual-core': {'LowerSorrow': {frozenset({'Glide', 'Wind'})}}, 'expert-lure': {'LowerSorrow': {frozenset({'Climb', 'Dash', 'Glide', 'DoubleJump', 'Bash'}), frozenset({'Dash', 'Glide', 'DoubleJump', 'WallJump', 'Bash'})}}, 'dbash': {'LowerSorrow': {frozenset({'Bash'})}}, 'expert-dboost': {'LowerSorrow': {frozenset({'Climb', 'ChargeJump', ('HC', 6)}), frozenset({'ChargeJump', ('HC', 6), 'WallJump'})}}, 'master-dboost': {'LowerSorrow': {frozenset({('AC', 12), ('HC', 4), 'ChargeJump', 'WallJump'}), frozenset({'Climb', ('HC', 4), 'ChargeJump', ('AC', 12)}), frozenset({('AC', 12), ('HC', 10), 'DoubleJump', 'WallJump'})}}}, 'SorrowMapstoneArea': {'glitched': {'HoruInnerDoor': {frozenset({'Dash'})}}}, 'SorrowTeleporter': {'casual-core': {'BelowSunstoneArea': {frozenset({'Climb', 'ChargeJump', 'DoubleJump'})}, 'AboveChargeJumpArea': {frozenset({'Climb', 'Stomp', 'ChargeJump'})}}, 'standard-core': {'BelowSunstoneArea': {frozenset({'Climb', 'Glide', 'ChargeJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'})}, 'AboveChargeJumpArea': {frozenset({'Climb', 'ChargeJump'})}}, 'gjump': {'BelowSunstoneArea': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'expert-dboost': {'BelowSunstoneArea': {frozenset({'Grenade', 'Stomp', ('HC', 2), 'Bash'}), frozenset({'Climb', 'ChargeJump', ('HC', 2)}), frozenset({'Glide', 'ChargeJump', 'WallJump', ('HC', 2)}), frozenset({'WallJump', 'Dash', ('HC', 2), 'ChargeJump', ('AC', 3)})}, 'AboveChargeJumpArea': {frozenset({('HC', 2), 'Glide', 'ChargeJump', 'DoubleJump', 'WallJump'})}}, 'master-core': {'BelowSunstoneArea': {frozenset({'Stomp', 'WallJump', 'Bash'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Climb', 'Stomp', 'Bash'})}, 'AboveChargeJumpArea': {frozenset({'Bash', 'ChargeJump'}), frozenset({'Stomp', 'Bash'})}}, 'master-dboost': {'BelowSunstoneArea': {frozenset({'Climb', ('AC', 12), 'ChargeJump', ('HC', 1)}), frozenset({('AC', 12), 'Dash', ('HC', 1), 'ChargeJump', 'WallJump'}), frozenset({('AC', 12), ('HC', 1), 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({('AC', 12), ('HC', 1), 'Glide', 'ChargeJump', 'WallJump'})}}, 'expert-core': {'AboveChargeJumpArea': {frozenset({'Glide', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Glide', 'ChargeJump', 'DoubleJump', 'WallJump', 'Bash'})}}, 'expert-abilities': {'AboveChargeJumpArea': {frozenset({'WallJump', 'Dash', 'ChargeJump', 'DoubleJump', ('AC', 3)})}}}, 'SpiderSacArea': {'casual-core': {'SpiderSacTetherArea': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'SpiderWaterArea': {frozenset({'DoubleJump'}), frozenset({'Glide'})}, 'SpiderSacEnergyNook': {frozenset({'DoubleJump'}), frozenset({'Glide'})}, 'SpiritTreeRefined': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Grenade', 'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'ChargeFlame', 'Climb'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Grenade', 'Climb'})}}, 'master-core': {'SpiderSacTetherArea': {frozenset({'DoubleJump'})}, 'SpiritTreeRefined': {frozenset({'Stomp', 'DoubleJump'}), frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'Grenade', 'DoubleJump'})}}, 'expert-abilities': {'SpiderWaterArea': {frozenset({'Dash', ('AC', 3)})}, 'SpiderSacEnergyNook': {frozenset({'Dash', ('AC', 3)})}}, 'standard-core': {'SpiritTreeRefined': {frozenset({'Climb', 'Stomp'}), frozenset({'Stomp', 'WallJump'}), frozenset({'Stomp', 'ChargeJump'})}}}, 'SpiderSacEnergyNook': {'master-abilities': {'ChargeFlameAreaPlantAccess': {frozenset({'ChargeFlame', ('AC', 3)})}}}, 'SpiderSacTetherArea': {'casual-core': {'SpiderWaterArea': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'SpiderSacEnergyNook': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}}, 'expert-abilities': {'SpiderWaterArea': {frozenset({'Grenade', 'Dash', ('AC', 6), 'Bash'}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}, 'SpiderSacEnergyNook': {frozenset({'Grenade', 'Dash', ('AC', 6), 'Bash'}), frozenset({('AC', 6), 'Dash', 'ChargeJump'})}}}, 'SpiderWaterArea': {'casual-core': {'SpiderSacEnergyNook': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'})}, 'SpiderSacArea': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Glide', 'Bash', 'WallJump'}), frozenset({'Climb', 'Bash', 'Glide'})}, 'HollowGrove': {frozenset({'Climb'}), frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Water'}), frozenset({'DoubleJump'})}, 'DeathGauntletRoof': {frozenset({'Stomp', 'WallJump', 'Water'}), frozenset({'Bash', 'Stomp', 'Water'}), frozenset({'Climb', 'Stomp', 'Water'})}}, 'standard-core': {'SpiderSacEnergyNook': {frozenset({'Dash', 'DoubleJump'}), frozenset({'Bash', 'DoubleJump'})}, 'SpiderSacArea': {frozenset({'Climb', 'Bash'}), frozenset({'Glide', 'Dash', 'WallJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Climb', 'Dash', 'Glide'})}, 'HollowGrove': {frozenset({'Bash'})}}, 'expert-core': {'SpiderSacEnergyNook': {frozenset({'DoubleJump'})}}, 'dbash': {'SpiderSacEnergyNook': {frozenset({'Bash'})}, 'SpiderSacArea': {frozenset({'Bash'})}}, 'expert-abilities': {'SpiderSacEnergyNook': {frozenset({'Dash', ('AC', 3)})}, 'SpiderSacArea': {frozenset({'Dash', ('AC', 6)})}}, 'gjump': {'SpiderSacEnergyNook': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'master-core': {'SpiderSacArea': {frozenset({'Climb', 'ChargeJump'})}}, 'master-abilities': {'HollowGrove': {frozenset({'Dash', ('AC', 6)})}}, 'expert-dboost': {'DeathGauntletRoof': {frozenset({'Climb', 'Stomp', ('HC', 2)}), frozenset({'Stomp', 'WallJump', ('HC', 2)}), frozenset({'Bash', 'Stomp', ('HC', 1)}), frozenset({'Stomp', 'DoubleJump', ('HC', 2)})}}, 'master-dboost': {'DeathGauntletRoof': {frozenset({'Climb', 'Stomp', ('AC', 12)}), frozenset({'Stomp', ('AC', 12), 'WallJump'}), frozenset({'Stomp', ('AC', 12), 'DoubleJump'})}}}, 'SpiritCavernsDoor': {'casual-core': {'SpiritCavernsDoorOpened': {frozenset({('KS', 2)})}}}, 'SpiritCavernsDoorOpened': {'casual-core': {'LowerSpiritCaverns': {frozenset({'ChargeJump'}), frozenset({'WallJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb'})}}, 'standard-lure': {'LowerSpiritCaverns': {frozenset({'Bash'})}}, 'expert-abilities': {'LowerSpiritCaverns': {frozenset({'Dash', ('AC', 6)})}}, 'master-core': {'LowerSpiritCaverns': {frozenset({'DoubleJump'})}}}, 'SpiritTreeDoor': {'casual-core': {'SpiritTreeDoorOpened': {frozenset({('KS', 4)})}}}, 'SpiritTreeDoorOpened': {'casual-core': {'SpiritTreeRefined': {frozenset({'Climb'}), frozenset({'Bash'}), frozenset({'WallJump'})}}, 'casual-dboost': {'SpiritTreeRefined': {frozenset({'ChargeJump'})}}, 'master-core': {'SpiritTreeRefined': {frozenset({'DoubleJump'})}}}, 'SpiritTreeRefined': {'casual-core': {'SpiritTreeDoor': {frozenset({'Open'})}, 'ValleyEntry': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}, 'SpiderSacArea': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'ChargeFlame', 'Climb', 'Glide'}), frozenset({'Grenade', 'WallJump'}), frozenset({'ChargeFlame', 'Climb', 'DoubleJump'}), frozenset({'ChargeFlame', 'Climb', 'Dash'}), frozenset({'Grenade', 'Climb', 'Glide'}), frozenset({'Grenade', 'Climb', 'DoubleJump'}), frozenset({'Grenade', 'ChargeJump'}), frozenset({'Grenade', 'Climb', 'Dash'}), frozenset({'Grenade', 'Bash'}), frozenset({'ChargeFlame', 'ChargeJump'})}}, 'standard-core': {'ValleyEntry': {frozenset({'Stomp', 'DoubleJump'}), frozenset({'Climb', 'Stomp'}), frozenset({'Stomp', 'WallJump'}), frozenset({'Stomp', 'ChargeJump'})}}, 'expert-abilities': {'ValleyEntry': {frozenset({'Dash', ('AC', 6)})}, 'SpiderSacArea': {frozenset({'Climb', 'Dash', ('AC', 6)}), frozenset({'Dash', ('AC', 6), 'WallJump'})}}, 'expert-core': {'SpiderSacArea': {frozenset({'ChargeFlame', 'Climb'}), frozenset({'Grenade', 'Climb'})}}, 'master-core': {'SpiderSacArea': {frozenset({'ChargeFlame', 'DoubleJump'}), frozenset({'Grenade', 'DoubleJump'})}}, 'master-abilities': {'SpiderSacArea': {frozenset({'Dash', ('AC', 6), 'DoubleJump'})}}}, 'SunkenGladesRunaway': {'casual-core': {'GladesMain': {frozenset({('KS', 2)}), frozenset({'OpenWorld'})}, 'BlackrootDarknessRoom': {frozenset({'ChargeJump'}), frozenset({'Climb'}), frozenset({'Grenade', 'Bash'}), frozenset({'WallJump'})}, 'DeathGauntletDoor': {frozenset({'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'SpiritTreeRefined': {frozenset({'TPGrove'})}, 'MoonGrotto': {frozenset({'TPGrotto'})}, 'SwampTeleporter': {frozenset({'TPSwamp'})}, 'ValleyTeleporter': {frozenset({'TPValley'})}, 'SorrowTeleporter': {frozenset({'TPSorrow'})}, 'GinsoTeleporter': {frozenset({'TPGinso'})}, 'ForlornTeleporter': {frozenset({'TPForlorn'})}, 'HoruTeleporter': {frozenset({'TPHoru', 'HoruKey'})}}, 'glitched': {'LowerChargeFlameArea': {frozenset({'Grenade'})}}, 'master-core': {'BlackrootDarknessRoom': {frozenset({'DoubleJump'})}, 'DeathGauntletDoor': {frozenset({'DoubleJump'})}}, 'casual-dboost': {'DeathGauntletDoor': {frozenset({'Climb'}), frozenset({'WallJump'})}}, 'standard-lure': {'DeathGauntletDoor': {frozenset({'Bash'})}}}, 'SunstoneArea': {'casual-core': {'UpperSorrow': {frozenset({'Stomp'})}, 'SorrowTeleporter': {frozenset({'Climb', 'ChargeJump', 'DoubleJump'})}}, 'standard-core': {'UpperSorrow': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-dboost': {'SorrowTeleporter': {frozenset({'ChargeJump', 'DoubleJump', 'WallJump', ('HC', 2)})}}}, 'Swamp': {'casual-core': {'SwampDrainlessArea': {frozenset({'Stomp'})}, 'SwampKeyDoorPlatform': {frozenset({'Grenade', 'Bash'}), frozenset({'Glide'}), frozenset({'ChargeJump'}), frozenset({'Water'}), frozenset({'DoubleJump'})}, 'SwampWater': {frozenset({'Water'})}}, 'expert-core': {'SwampDrainlessArea': {frozenset({'Climb', 'ChargeJump'})}}, 'casual-dboost': {'SwampKeyDoorPlatform': {frozenset({'Free'})}}, 'standard-core': {'SwampKeyDoorPlatform': {frozenset({'Dash'})}}, 'master-dboost': {'SwampWater': {frozenset({('HC', 4), ('AC', 12)}), frozenset({('HC', 12)})}}}, 'SwampEntryArea': {'casual-core': {'SwampDrainlessArea': {frozenset({'Climb', 'Stomp'}), frozenset({'Grenade', 'Stomp', 'Bash'}), frozenset({'Stomp', 'WallJump'}), frozenset({'Stomp', 'ChargeJump'})}, 'Swamp': {frozenset({'Stomp', 'ChargeJump'})}}, 'standard-core': {'SwampDrainlessArea': {frozenset({'Climb', 'ChargeJump'})}, 'Swamp': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-lure': {'SwampDrainlessArea': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'Swamp': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Grenade', 'Bash'})}}}, 'SwampKeyDoorOpened': {'casual-core': {'RightSwamp': {frozenset({'Bash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'}), frozenset({'Climb', 'Bash', 'Grenade'})}}, 'standard-core': {'RightSwamp': {frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'Glide', 'ChargeJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}}, 'standard-dboost': {'RightSwamp': {frozenset({'Climb', 'ChargeJump', ('HC', 0)}), frozenset({'ChargeJump', ('HC', 0), 'WallJump'}), frozenset({('HC', 0), 'Glide', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Glide', 'DoubleJump', ('HC', 0)})}}, 'expert-dboost': {'RightSwamp': {frozenset({'Climb', 'DoubleJump', ('HC', 2)}), frozenset({('HC', 0), 'ChargeJump', 'DoubleJump'}), frozenset({'Bash', ('HC', 0), 'WallJump', 'Water'}), frozenset({'DoubleJump', 'WallJump', ('HC', 2)}), frozenset({'Climb', 'Dash', ('AC', 6), ('HC', 0)}), frozenset({('AC', 6), ('HC', 0), 'Dash', ('EC', 3), 'Bash'}), frozenset({'Dash', ('AC', 6), ('HC', 0), 'WallJump'})}}, 'expert-abilities': {'RightSwamp': {frozenset({('EC', 2), 'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6), ('EC', 2)})}}, 'dbash': {'RightSwamp': {frozenset({'Bash', 'Water'}), frozenset({'Bash', ('HC', 2)})}}, 'master-dboost': {'RightSwamp': {frozenset({('HC', 9), 'WallJump'}), frozenset({('AC', 12), 'DoubleJump', ('HC', 1)}), frozenset({('HC', 4), 'DoubleJump'}), frozenset({('AC', 12), 'WallJump', 'Water', ('HC', 2)}), frozenset({('HC', 4), ('AC', 12), 'WallJump'}), frozenset({('HC', 6), 'WallJump', 'Water'})}}, 'master-abilities': {'RightSwamp': {frozenset({('EC', 2), 'Dash', ('AC', 6), 'DoubleJump'})}}, 'gjump': {'RightSwamp': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}}, 'SwampKeyDoorPlatform': {'casual-core': {'SwampKeyDoorOpened': {frozenset({('KS', 2)})}, 'InnerSwampSkyArea': {frozenset({'Glide', 'Wind'})}}, 'standard-core': {'InnerSwampSkyArea': {frozenset({'Climb', 'Glide', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump', 'DoubleJump'})}}, 'dbash': {'InnerSwampSkyArea': {frozenset({'Bash'})}}, 'gjump': {'InnerSwampSkyArea': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}}, 'SwampTeleporter': {'glitched': {'OuterSwampMortarAbilityCellLedge': {frozenset({'Free'})}}}, 'TopGinsoTree': {'casual-core': {'GinsoEscape': {frozenset({'Bash', 'ChargeJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Bash', 'DoubleJump'})}}, 'standard-core': {'GinsoEscape': {frozenset({'Bash'}), frozenset({'Stomp', 'ChargeJump'})}}, 'standard-dboost': {'GinsoEscape': {frozenset({('HC', 0), 'Climb', 'Dash', 'Stomp', 'DoubleJump'}), frozenset({('HC', 0), 'Glide', 'Stomp', 'DoubleJump', 'WallJump'}), frozenset({('HC', 0), 'Climb', 'Glide', 'Stomp', 'DoubleJump'}), frozenset({('HC', 0), 'Dash', 'Stomp', 'DoubleJump', 'WallJump'})}}, 'expert-abilities': {'GinsoEscape': {frozenset({'Stomp', ('AC', 6), 'Dash'})}}, 'master-abilities': {'GinsoEscape': {frozenset({'Stomp', ('AC', 12), 'DoubleJump'})}}, 'master-dboost': {'GinsoEscape': {frozenset({('HC', 0), 'Stomp', 'DoubleJump', 'Dash'}), frozenset({'Glide', 'Stomp', 'DoubleJump', ('HC', 0)})}}}, 'UpperGinsoDoorClosed': {'casual-core': {'UpperGinsoDoorOpened': {frozenset({('KS', 4)})}}}, 'UpperGinsoDoorOpened': {'casual-core': {'GinsoTeleporter': {frozenset({'Glide', 'Bash'}), frozenset({'Bash', 'DoubleJump'})}, 'UpperGinsoTree': {frozenset({'Open', 'Bash'}), frozenset({'Open', 'DoubleJump'}), frozenset({'Glide', 'Open'})}}, 'standard-core': {'GinsoTeleporter': {frozenset({'Bash'})}}, 'expert-dboost': {'GinsoTeleporter': {frozenset({'ChargeJump', ('HC', 2)}), frozenset({('HC', 0), 'ChargeJump', 'DoubleJump'})}}, 'master-dboost': {'GinsoTeleporter': {frozenset({('AC', 12), 'DoubleJump', 'WallJump', ('HC', 2)})}}, 'casual-dboost': {'UpperGinsoTree': {frozenset({'Open', ('HC', 0)})}}, 'standard-abilities': {'UpperGinsoTree': {frozenset({'Open', 'Dash', ('AC', 3)})}}}, 'UpperGinsoRedirectArea': {'casual-core': {'UpperGinsoTree': {frozenset({'ChargeJump'}), frozenset({'Bash'})}, 'BashTree': {frozenset({'DoubleJump'}), frozenset({'Bash'})}}, 'master-abilities': {'UpperGinsoTree': {frozenset({'ChargeFlame', 'Climb', ('AC', 12), 'DoubleJump'}), frozenset({'Grenade', ('AC', 12), 'DoubleJump', 'WallJump'}), frozenset({'Grenade', 'Climb', ('AC', 12), 'DoubleJump'}), frozenset({'Stomp', ('AC', 12), 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Stomp', ('AC', 12), 'DoubleJump'}), frozenset({'ChargeFlame', ('AC', 12), 'DoubleJump', 'WallJump'})}}, 'standard-abilities': {'BashTree': {frozenset({'Dash', ('AC', 3)})}}, 'standard-dboost': {'BashTree': {frozenset({'Glide', ('HC', 1)}), frozenset({'Dash', ('HC', 1)}), frozenset({'WallJump', ('HC', 1)}), frozenset({'ChargeJump', ('HC', 1)}), frozenset({'Climb', ('HC', 1)})}}}, 'UpperGinsoTree': {'casual-core': {'UpperGinsoDoorClosed': {frozenset({'Free'})}, 'UpperGinsoRedirectArea': {frozenset({'Bash', 'ChargeJump'}), frozenset({'Stomp'})}}, 'standard-core': {'UpperGinsoRedirectArea': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-core': {'UpperGinsoRedirectArea': {frozenset({'ChargeFlame', 'ChargeJump'})}}, 'expert-abilities': {'UpperGinsoRedirectArea': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'master-core': {'UpperGinsoRedirectArea': {frozenset({'Bash'})}}}, 'UpperGrotto': {'casual-core': {'OuterSwampMortarAbilityCellLedge': {frozenset({'ChargeJump'})}, 'MoonGrottoStompPlantAccess': {frozenset({'Stomp'})}, 'OuterSwampLowerArea': {frozenset({'Grenade', 'Bash'}), frozenset({'Climb'}), frozenset({'WallJump'}), frozenset({'ChargeJump'})}, 'Iceless': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Glide', 'WallJump'})}, 'MoonGrottoAboveTeleporter': {frozenset({'Glide'}), frozenset({'Climb'}), frozenset({'Dash'}), frozenset({'WallJump'}), frozenset({'DoubleJump'})}}, 'standard-core': {'MoonGrottoStompPlantAccess': {frozenset({'Climb', 'ChargeJump'})}, 'Iceless': {frozenset({'Grenade', 'Bash'})}, 'MoonGrottoAboveTeleporter': {frozenset({'Grenade', 'Bash'})}}, 'master-core': {'MoonGrottoStompPlantAccess': {frozenset({'Bash'})}, 'Iceless': {frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Bash'})}}, 'expert-core': {'OuterSwampLowerArea': {frozenset({'DoubleJump'})}}, 'standard-dboost': {'Iceless': {frozenset({'ChargeJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', 'ChargeJump', ('HC', 1)})}}, 'standard-abilities': {'Iceless': {frozenset({'Climb', 'Dash', ('AC', 3)})}}, 'gjump': {'Iceless': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'glitched': {'MoonGrottoAboveTeleporter': {frozenset({'Free'})}}}, 'UpperSorrow': {'glitched': {'SunstoneArea': {frozenset({'Glide', 'ChargeJump'})}, 'SorrowTeleporter': {frozenset({'Climb', 'Glide', 'ChargeJump'})}}, 'casual-core': {'ChargeJumpDoor': {frozenset({'Free'})}}}, 'UpperSpiritCaverns': {'casual-core': {'SpiritTreeDoor': {frozenset({'Free'})}}}, 'ValleyEntry': {'casual-core': {'ValleyEntryTree': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Climb', 'Bash'}), frozenset({'WallJump'})}, 'ValleyEntryTreePlantAccess': {frozenset({'Grenade', 'ChargeJump'}), frozenset({'ChargeFlame', 'ChargeJump'}), frozenset({'Grenade', 'Bash'})}, 'ValleyPostStompDoor': {frozenset({'Stomp', 'ChargeJump', 'WallJump'}), frozenset({'OpenWorld', 'DoubleJump', 'WallJump'}), frozenset({'Stomp', 'WallJump', 'Bash'}), frozenset({'Climb', 'Stomp', 'ChargeJump'}), frozenset({'Stomp', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump', 'OpenWorld'}), frozenset({'Climb', 'Stomp', 'DoubleJump'}), frozenset({'ChargeJump', 'OpenWorld', 'WallJump'}), frozenset({'Climb', 'OpenWorld', 'DoubleJump'}), frozenset({'Bash', 'OpenWorld', 'WallJump'})}, 'ValleyThreeBirdLever': {frozenset({'Glide', 'OpenWorld', 'Wind'}), frozenset({'Bash', 'OpenWorld'}), frozenset({'Climb', 'Glide', 'ChargeJump', 'OpenWorld'}), frozenset({'Climb', 'OpenWorld', 'ChargeJump', 'DoubleJump'})}, 'ValleyStompFloor': {frozenset({'Glide', 'OpenWorld', 'Wind'}), frozenset({'OpenWorld', 'ChargeJump', 'DoubleJump'}), frozenset({'Bash', 'OpenWorld'}), frozenset({'Glide', 'ChargeJump', 'OpenWorld'}), frozenset({'Climb', 'ChargeJump', 'OpenWorld'}), frozenset({'Glide', 'DoubleJump', 'OpenWorld'})}, 'SpiritTreeRefined': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}}, 'standard-lure': {'ValleyEntryTree': {frozenset({'Bash'})}}, 'expert-dboost': {'ValleyEntryTree': {frozenset({'ChargeJump', ('HC', 1)})}, 'ValleyPostStompDoor': {frozenset({'Stomp', 'ChargeJump', ('HC', 1)}), frozenset({'ChargeJump', 'OpenWorld', ('HC', 1)}), frozenset({'Bash', 'ChargeJump', ('HC', 1)})}}, 'expert-abilities': {'ValleyEntryTree': {frozenset({'Dash', ('AC', 6)})}, 'ValleyEntryTreePlantAccess': {frozenset({('EC', 2), 'Dash', ('AC', 6)})}, 'ValleyThreeBirdLever': {frozenset({'Dash', ('AC', 6), 'OpenWorld'})}, 'ValleyStompFloor': {frozenset({'Dash', ('AC', 6), 'OpenWorld'})}, 'SpiritTreeRefined': {frozenset({'Dash', ('AC', 6)})}}, 'expert-core': {'ValleyEntryTreePlantAccess': {frozenset({'ChargeFlame', 'WallJump'}), frozenset({'Grenade'})}}, 'expert-lure': {'ValleyPostStompDoor': {frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'Climb', 'Bash', 'ChargeJump'}), frozenset({'Bash', 'WallJump'})}}, 'standard-core': {'ValleyThreeBirdLever': {frozenset({'Dash', 'ChargeJump', 'DoubleJump', 'OpenWorld'})}, 'ValleyStompFloor': {frozenset({'Glide', 'Dash', 'OpenWorld'}), frozenset({'Dash', 'DoubleJump', 'OpenWorld'})}}, 'gjump': {'ValleyThreeBirdLever': {frozenset({'Climb', 'OpenWorld', 'ChargeJump', 'Grenade'})}}, 'standard-abilities': {'ValleyStompFloor': {frozenset({'Dash', 'ChargeJump', 'OpenWorld', ('AC', 3)})}}, 'standard-dboost': {'ValleyStompFloor': {frozenset({'OpenWorld', ('HC', 1)})}}}, 'ValleyEntryTree': {'casual-core': {'ValleyEntryTreePlantAccess': {frozenset({'Climb', 'ChargeJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Bash'}), frozenset({'Glide'})}, 'ValleyPostStompDoor': {frozenset({'OpenWorld'})}}, 'expert-core': {'ValleyEntryTreePlantAccess': {frozenset({'Grenade'})}}, 'expert-abilities': {'ValleyEntryTreePlantAccess': {frozenset({'Dash', ('AC', 6)})}}}, 'ValleyForlornApproach': {'casual-core': {'OutsideForlornCliff': {frozenset({'ChargeJump'}), frozenset({'Bash'})}, 'ValleyStompFloor': {frozenset({'ChargeJump'})}}, 'standard-core': {'OutsideForlornCliff': {frozenset({'Stomp'})}}, 'master-core': {'ValleyStompFloor': {frozenset({'Bash'})}}}, 'ValleyMain': {'casual-core': {'WilhelmLedge': {frozenset({'Glide', 'Wind'}), frozenset({'Bash'})}, 'MistyEntrance': {frozenset({'Glide'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Dash'}), frozenset({'Bash'}), frozenset({'DoubleJump'})}}, 'expert-abilities': {'WilhelmLedge': {frozenset({('EC', 2), 'Dash', ('AC', 6)})}}, 'gjump': {'WilhelmLedge': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}}, 'ValleyPostStompDoor': {'casual-core': {'ValleyRight': {frozenset({'Climb', 'Bash'}), frozenset({'Bash', 'ChargeJump'}), frozenset({'Bash', 'WallJump'}), frozenset({'Grenade', 'Bash'})}, 'ValleyEntry': {frozenset({'OpenWorld'})}, 'ValleyEntryTree': {frozenset({'Bash', 'OpenWorld'}), frozenset({'OpenWorld', 'WallJump'}), frozenset({'ChargeJump', 'OpenWorld'}), frozenset({'OpenWorld', 'DoubleJump'}), frozenset({'Climb', 'OpenWorld'})}}, 'expert-dboost': {'ValleyRight': {frozenset({('HC', 4), 'ChargeJump', 'DoubleJump', 'WallJump'})}}, 'dbash': {'ValleyRight': {frozenset({'Bash'})}}, 'master-dboost': {'ValleyRight': {frozenset({('HC', 0), ('AC', 12), 'Climb', 'ChargeJump', 'DoubleJump'}), frozenset({('HC', 0), ('AC', 12), 'ChargeJump', 'DoubleJump', 'WallJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump', ('HC', 8)})}}, 'gjump': {'ValleyRight': {frozenset({('AC', 12), 'Climb', 'Grenade', 'Stomp', 'ChargeJump', 'DoubleJump'}), frozenset({('AC', 12), 'Climb', ('HC', 2), 'Grenade', 'ChargeJump'}), frozenset({'Climb', 'Grenade', 'Stomp', 'ChargeJump', 'DoubleJump', ('HC', 1)}), frozenset({('AC', 6), 'Climb', 'Dash', 'Grenade', 'ChargeJump'}), frozenset({'Climb', ('HC', 4), 'ChargeJump', 'Grenade'})}}, 'standard-core': {'ValleyEntryTree': {frozenset({'Dash', 'OpenWorld'})}}}, 'ValleyRight': {'expert-dboost': {'ValleyPostStompDoor': {frozenset({'DoubleJump', ('HC', 1)})}}, 'master-dboost': {'ValleyPostStompDoor': {frozenset({('HC', 4)}), frozenset({('AC', 12), ('HC', 2)})}}, 'casual-core': {'ValleyStomplessApproach': {frozenset({'Glide', 'Wind'}), frozenset({'DoubleJump', 'WallJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'Bash', 'DoubleJump'}), frozenset({'Grenade', 'Bash', 'Climb'}), frozenset({'Bash', 'WallJump'})}}, 'expert-abilities': {'ValleyStomplessApproach': {frozenset({'Dash', ('AC', 6), 'WallJump'})}}}, 'ValleyStompFloor': {'casual-core': {'ValleyForlornApproach': {frozenset({'Stomp'})}, 'ValleyThreeBirdLever': {frozenset({'Climb', 'ChargeJump'}), frozenset({'Bash'}), frozenset({'ChargeJump', 'DoubleJump', 'WallJump'})}, 'ValleyEntry': {frozenset({'OpenWorld', 'ChargeJump', 'DoubleJump'}), frozenset({'Bash', 'OpenWorld'}), frozenset({'Glide', 'ChargeJump', 'OpenWorld'})}}, 'standard-core': {'ValleyForlornApproach': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-lure': {'ValleyForlornApproach': {frozenset({'Bash'})}}, 'standard-dboost': {'ValleyEntry': {frozenset({'ChargeJump', 'OpenWorld', ('HC', 1)})}}, 'expert-dboost': {'ValleyEntry': {frozenset({('HC', 0), 'OpenWorld', 'DoubleJump'}), frozenset({'OpenWorld', 'ChargeJump', ('HC', 0)})}}, 'expert-abilities': {'ValleyEntry': {frozenset({'Dash', ('AC', 6), 'OpenWorld'})}}}, 'ValleyStompless': {'casual-core': {'WilhelmLedge': {frozenset({'Glide', 'Wind'}), frozenset({'Bash'})}, 'ValleyStomplessApproach': {frozenset({'Bash'}), frozenset({'Glide'})}, 'MistyEntrance': {frozenset({'Bash', 'OpenWorld'}), frozenset({'Climb', 'ChargeJump', 'OpenWorld'}), frozenset({'OpenWorld', 'DoubleJump'}), frozenset({'Dash', 'OpenWorld'}), frozenset({'Glide', 'OpenWorld'})}, 'LowerValley': {frozenset({'OpenWorld'})}, 'LowerValleyPlantApproach': {frozenset({'OpenWorld'})}}, 'expert-abilities': {'WilhelmLedge': {frozenset({('EC', 2), 'Dash', ('AC', 6)}), frozenset({'Dash', ('AC', 6), 'DoubleJump'})}, 'ValleyStomplessApproach': {frozenset({'Dash', ('AC', 6), ('EC', 3)})}}, 'expert-core': {'ValleyMain': {frozenset({'Bash'})}}, 'master-core': {'ValleyMain': {frozenset({'ChargeFlame'}), frozenset({'Grenade'})}}, 'expert-dboost': {'ValleyStomplessApproach': {frozenset({'Dash', ('AC', 3), ('HC', 1)}), frozenset({'DoubleJump', ('HC', 1)})}}, 'master-dboost': {'ValleyStomplessApproach': {frozenset({('HC', 7)}), frozenset({('HC', 4), 'ChargeJump'}), frozenset({('AC', 12), 'ChargeJump', ('HC', 2)}), frozenset({('HC', 4), ('AC', 12)})}}}, 'ValleyStomplessApproach': {'casual-core': {'ValleyStompless': {frozenset({'Bash'})}}, 'expert-dboost': {'ValleyStompless': {frozenset({'ChargeJump', 'DoubleJump', 'WallJump', ('HC', 1)}), frozenset({'Climb', 'ChargeJump', 'DoubleJump', ('HC', 1)})}}, 'expert-abilities': {'ValleyStompless': {frozenset({('EC', 2), 'Dash', 'DoubleJump', 'WallJump'}), frozenset({'Climb', 'Dash', 'DoubleJump', ('EC', 2)})}}, 'master-dboost': {'ValleyStompless': {frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}}}, 'ValleyTeleporter': {'casual-core': {'ValleyPostStompDoor': {frozenset({'Bash'}), frozenset({'Glide'})}, 'ValleyRight': {frozenset({'Climb', 'Glide', 'ChargeJump'}), frozenset({'Climb', 'Glide', 'DoubleJump'}), frozenset({'Glide', 'DoubleJump', 'WallJump'}), frozenset({'Bash'})}, 'MistyEntrance': {frozenset({'Glide', 'OpenWorld'})}, 'LowerValley': {frozenset({'OpenWorld'})}, 'LowerValleyPlantApproach': {frozenset({'OpenWorld'})}, 'ValleyStompless': {frozenset({'Climb', 'ChargeJump', 'OpenWorld'}), frozenset({'Glide', 'OpenWorld', 'Wind'})}}, 'expert-abilities': {'ValleyPostStompDoor': {frozenset({'Dash', ('AC', 6), 'DoubleJump'}), frozenset({'Dash', ('AC', 6), ('EC', 3)})}, 'ValleyRight': {frozenset({'Dash', ('AC', 6)})}, 'MistyEntrance': {frozenset({'Dash', 'DoubleJump', ('AC', 3), 'OpenWorld'}), frozenset({'Dash', ('AC', 6), 'OpenWorld'})}, 'ValleyStompless': {frozenset({'Dash', ('AC', 6), 'OpenWorld'})}}, 'master-core': {'ValleyPostStompDoor': {frozenset({'DoubleJump'})}}, 'expert-dboost': {'ValleyRight': {frozenset({'DoubleJump', 'WallJump', ('HC', 1)}), frozenset({'Glide', 'WallJump', ('HC', 1)}), frozenset({'Climb', 'DoubleJump', ('HC', 1)}), frozenset({'Climb', 'Glide', ('HC', 1)})}}, 'gjump': {'ValleyRight': {frozenset({'Climb', 'ChargeJump', 'Grenade'})}}, 'master-abilities': {'ValleyRight': {frozenset({('AC', 12), 'DoubleJump'})}, 'ValleyStompless': {frozenset({('AC', 12), 'DoubleJump', 'WallJump', 'OpenWorld'})}}, 'standard-core': {'MistyEntrance': {frozenset({'Grenade', 'Bash', 'DoubleJump', 'OpenWorld'})}}, 'standard-abilities': {'MistyEntrance': {frozenset({'OpenWorld', 'Dash', 'ChargeJump', 'DoubleJump', ('AC', 3)})}}, 'expert-core': {'MistyEntrance': {frozenset({'Bash', 'ChargeJump', 'DoubleJump', 'OpenWorld'}), frozenset({'Dash', 'ChargeJump', 'DoubleJump', 'OpenWorld'}), frozenset({'Grenade', 'Bash', 'OpenWorld'})}, 'ValleyStompless': {frozenset({'Climb', 'Bash', 'Grenade', 'OpenWorld'}), frozenset({'Grenade', 'Bash', 'OpenWorld', 'WallJump'})}}, 'master-lure': {'ValleyStompless': {frozenset({'Bash', 'OpenWorld', 'WallJump'})}}}, 'ValleyThreeBirdLever': {'casual-core': {'ValleyEntry': {frozenset({'Climb', 'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Bash'}), frozenset({'Glide'})}, 'LowerValley': {frozenset({'Glide', 'Wind'}), frozenset({'Glide', 'DoubleJump'})}}, 'standard-abilities': {'ValleyEntry': {frozenset({'Dash', ('AC', 3)})}, 'LowerValley': {frozenset({'Dash', ('AC', 3)})}}, 'standard-dboost': {'ValleyEntry': {frozenset({('HC', 4)})}, 'LowerValley': {frozenset({('HC', 4)})}}, 'expert-dboost': {'ValleyEntry': {frozenset({'Climb', ('HC', -1)}), frozenset({('HC', -1), 'WallJump'}), frozenset({('HC', -1), 'ChargeJump'})}, 'LowerValley': {frozenset({('HC', 2)})}}, 'standard-core': {'LowerValley': {frozenset({'Glide', 'Dash'}), frozenset({'Dash', 'DoubleJump'})}}, 'dbash': {'LowerValley': {frozenset({'Bash'})}}}, 'WaterVeinArea': {'casual-core': {'LeftGumoHideout': {frozenset({'ChargeJump'}), frozenset({'Glide', 'Wind'}), frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'})}, 'LowerLeftGumoHideout': {frozenset({'ChargeJump'}), frozenset({'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Glide'})}, 'MoonGrotto': {frozenset({'DoubleJump', 'WallJump'}), frozenset({'ChargeJump', 'DoubleJump'}), frozenset({'Grenade', 'Bash'}), frozenset({'Climb', 'Glide'}), frozenset({'Glide', 'ChargeJump'}), frozenset({'Climb', 'ChargeJump'}), frozenset({'Climb', 'DoubleJump'}), frozenset({'Glide', 'WallJump'})}}, 'standard-core': {'LeftGumoHideout': {frozenset({'Dash'})}, 'LowerLeftGumoHideout': {frozenset({'Dash'})}, 'MoonGrotto': {frozenset({'Climb', 'Dash'}), frozenset({'Dash', 'WallJump'})}}}, 'WilhelmLedge': {'casual-core': {'SorrowBashLedge': {frozenset({'Glide', 'Wind'}), frozenset({'Dash', 'DoubleJump', 'WallJump'}), frozenset({'Glide', 'ChargeJump', 'WallJump'}), frozenset({'Bash'}), frozenset({'Climb', 'Glide', 'ChargeJump'})}, 'ValleyStompless': {frozenset({'Bash'}), frozenset({'Glide'})}, 'ValleyMain': {frozenset({'Stomp'})}}, 'standard-core': {'SorrowBashLedge': {frozenset({'Glide', 'Dash', 'Climb', 'DoubleJump'})}, 'ValleyMain': {frozenset({'Climb', 'ChargeJump'})}}, 'expert-abilities': {'SorrowBashLedge': {frozenset({'Dash', ('AC', 6), 'WallJump'}), frozenset({'Climb', 'Dash', ('AC', 6)})}, 'ValleyStompless': {frozenset({'Dash', ('AC', 6)})}}, 'master-abilities': {'SorrowBashLedge': {frozenset({'Climb', ('AC', 12), 'DoubleJump'}), frozenset({('AC', 12), 'DoubleJump', 'WallJump'})}, 'ValleyStompless': {frozenset({('AC', 12), 'DoubleJump'})}, 'ValleyMain': {frozenset({'Dash', 'ChargeJump', ('AC', 3)})}}, 'standard-abilities': {'ValleyStompless': {frozenset({'Dash', 'DoubleJump', ('AC', 3)})}}, 'standard-lure': {'ValleyMain': {frozenset({'HoruKey'})}}, 'expert-core': {'ValleyMain': {frozenset({'Grenade', 'Bash', 'ChargeJump'})}}, 'master-core': {'ValleyMain': {frozenset({'Bash'})}}, 'glitched': {'ValleyMain': {frozenset({'ChargeJump'})}}}} From f5afc84cd23d4dda875e2bd9fa8a8c5ffdbafcc4 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 6 Oct 2021 11:41:57 +0200 Subject: [PATCH 24/27] Tests: remove a breakpoint condition that was left ;P --- test/Reachability.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/Reachability.py b/test/Reachability.py index 31226822..73310ab7 100644 --- a/test/Reachability.py +++ b/test/Reachability.py @@ -27,6 +27,4 @@ class TestBase(unittest.TestCase): state = world.get_all_state(False) for location in world.get_locations(): with self.subTest("Location should be reached", location=location): - if not location.can_reach(state): - print("Bla!") self.assertTrue(location.can_reach(state)) From 1985423a97cfd6548bde33d0b45f21d0a91797ac Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Thu, 7 Oct 2021 04:31:03 +0200 Subject: [PATCH 25/27] LttP: fix ER spoiler writing --- BaseClasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index 58009b6c..423ffbd5 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1226,7 +1226,7 @@ class Spoiler(): outfile.write('Item Functionality: %s\n' % self.world.item_functionality[player]) outfile.write('Entrance Shuffle: %s\n' % self.world.shuffle[player]) if self.world.shuffle[player] != "vanilla": - outfile.write('Entrance Shuffle Seed %s\n' % self.world.er_seeds[player]) + outfile.write('Entrance Shuffle Seed %s\n' % self.world.worlds[player].er_seed) outfile.write('Pyramid hole pre-opened: %s\n' % ( 'Yes' if self.world.open_pyramid[player] else 'No')) outfile.write('Shop inventory shuffle: %s\n' % From cd53dcfe431c9c2c7daf13a2bd16cc410816d549 Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Fri, 8 Oct 2021 05:08:05 -0500 Subject: [PATCH 26/27] Fix typo --- worlds/ror2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/ror2/__init__.py b/worlds/ror2/__init__.py index 4aa6f278..329dc4c5 100644 --- a/worlds/ror2/__init__.py +++ b/worlds/ror2/__init__.py @@ -43,7 +43,7 @@ class RiskOfRainWorld(World): "Item Scrap, White": self.world.random.randint(0, 100), "Common Item": self.world.random.randint(0, 100), "Uncommon Item": self.world.random.randint(0, 70), - "Legendary Item": self.world.random.randint(0, 300), + "Legendary Item": self.world.random.randint(0, 30), "Boss Item": self.world.random.randint(0, 20), "Lunar Item": self.world.random.randint(0, 60), "Equipment": self.world.random.randint(0, 40) From 9ebab4a3820af8263004a6773e92eea79c99b067 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 8 Oct 2021 12:16:15 +0200 Subject: [PATCH 27/27] Core: fix set_seed argument order --- Main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Main.py b/Main.py index 389c8b25..8e26a1e5 100644 --- a/Main.py +++ b/Main.py @@ -30,7 +30,7 @@ def main(args, seed=None): world = MultiWorld(args.multi) logger = logging.getLogger() - world.set_seed(args.race, str(args.outputname if args.outputname else world.seed)) + world.set_seed(secure=args.race, name=str(args.outputname if args.outputname else world.seed)) world.shuffle = args.shuffle.copy() world.logic = args.logic.copy()